using DocumentCreationSystem.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 分步执行写书服务
    /// 提供分步骤的书籍创作控制，让用户可以自由控制每个创作阶段
    /// </summary>
    public class StepByStepWritingService
    {
        private readonly ILogger<StepByStepWritingService> _logger;
        private readonly IAIService _aiService;
        private readonly INovelCreationService _novelCreationService;
        private readonly IDataStorageService _dataStorage;
        private readonly WorldSettingService _worldSettingService;
        private readonly ChapterContinuityService _continuityService;
        private readonly EnhancedWorldSettingManager _enhancedWorldSettingManager;
        private readonly IProjectToolsService? _projectToolsService;
        private readonly NetworkRecoveryService? _networkRecovery;
        private readonly ResumableCreationService? _resumableCreation;
        private readonly IServiceProvider? _serviceProvider;
        private readonly IFileNamingService _fileNamingService;
        private readonly ContentQualityService _contentQualityService;
        private readonly UnifiedChapterSaveService _chapterSaveService;
        private readonly EnhancedChapterContentService? _enhancedChapterContentService;
        private readonly TimelineService? _timelineService;
        private readonly CharacterUpdateService? _characterUpdateService;
        private readonly ChapterOutlineUpdateService? _chapterOutlineUpdateService;

        public StepByStepWritingService(
            ILogger<StepByStepWritingService> logger,
            IAIService aiService,
            INovelCreationService novelCreationService,
            IDataStorageService dataStorage,
            WorldSettingService worldSettingService,
            ChapterContinuityService continuityService,
            EnhancedWorldSettingManager enhancedWorldSettingManager,
            IFileNamingService fileNamingService,
            ContentQualityService contentQualityService,
            UnifiedChapterSaveService chapterSaveService,
            IProjectToolsService? projectToolsService = null,
            NetworkRecoveryService? networkRecovery = null,
            ResumableCreationService? resumableCreation = null,
            IServiceProvider? serviceProvider = null,
            EnhancedChapterContentService? enhancedChapterContentService = null,
            TimelineService? timelineService = null,
            CharacterUpdateService? characterUpdateService = null,
            ChapterOutlineUpdateService? chapterOutlineUpdateService = null)
        {
            _logger = logger;
            _aiService = aiService;
            _novelCreationService = novelCreationService;
            _dataStorage = dataStorage;
            _worldSettingService = worldSettingService;
            _continuityService = continuityService;
            _enhancedWorldSettingManager = enhancedWorldSettingManager;
            _fileNamingService = fileNamingService;
            _contentQualityService = contentQualityService;
            _chapterSaveService = chapterSaveService;
            _projectToolsService = projectToolsService;
            _networkRecovery = networkRecovery;
            _resumableCreation = resumableCreation;
            _serviceProvider = serviceProvider;
            _enhancedChapterContentService = enhancedChapterContentService;
            _timelineService = timelineService;
            _characterUpdateService = characterUpdateService;
            _chapterOutlineUpdateService = chapterOutlineUpdateService;
        }

        /// <summary>
        /// 分步执行状态
        /// </summary>
        public class StepExecutionState
        {
            public int NovelProjectId { get; set; }
            public string BookTitle { get; set; } = string.Empty;
            public string CreativeDirection { get; set; } = string.Empty;
            public string WritingStyle { get; set; } = "现代网络小说";
            public int VolumeCount { get; set; } = 10;
            public int ChapterCount { get; set; } = 1000;
            public int WordsPerChapter { get; set; } = 6500;
            public string ProjectPath { get; set; } = string.Empty;
            
            // 步骤完成状态
            public bool OverallOutlineCompleted { get; set; }
            public bool VolumeOutlinesCompleted { get; set; }
            public bool ChapterOutlinesCompleted { get; set; }
            public bool WorldSettingCompleted { get; set; }
            
            // 生成的内容
            public string? OverallOutline { get; set; }
            public List<VolumeOutline> VolumeOutlines { get; set; } = new();
            public Dictionary<int, string> ChapterOutlines { get; set; } = new(); // 章节号 -> 细纲
            public Dictionary<int, string> ChapterContents { get; set; } = new(); // 章节号 -> 正文
            public Dictionary<int, string> ChapterTitles { get; set; } = new(); // 章节号 -> 标题
            public WorldSetting? WorldSetting { get; set; }
            
            // 当前执行状态
            public int CurrentVolume { get; set; } = 1;
            public int CurrentChapter { get; set; } = 1;
            public DateTime LastUpdated { get; set; } = DateTime.Now;
        }

        /// <summary>
        /// 步骤执行结果
        /// </summary>
        public class StepExecutionResult
        {
            public bool IsSuccess { get; set; }
            public string Message { get; set; } = string.Empty;
            public string? ErrorDetails { get; set; }
            public object? Data { get; set; }
            public int ProgressPercentage { get; set; }
        }

        /// <summary>
        /// 步骤1：生成全书大纲（支持网络恢复）
        /// </summary>
        public async Task<StepExecutionResult> GenerateOverallOutlineAsync(
            StepExecutionState state,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();

            try
            {
                _logger.LogInformation($"开始生成全书大纲，项目: {state.BookTitle}");

                // 如果有网络恢复服务，使用网络重试机制
                string outline;
                if (_networkRecovery != null)
                {
                    outline = await _networkRecovery.ExecuteWithNetworkRetryAsync(
                        async () => await _novelCreationService.GenerateOverallOutlineAsync(
                            state.NovelProjectId, state.CreativeDirection, state.VolumeCount),
                        maxRetries: 5,
                        networkRecoveryTimeout: TimeSpan.FromMinutes(10),
                        cancellationToken);
                }
                else
                {
                    outline = await _novelCreationService.GenerateOverallOutlineAsync(
                        state.NovelProjectId, state.CreativeDirection, state.VolumeCount);
                }

                cancellationToken.ThrowIfCancellationRequested();

                // 进行大纲质量检查
                var qualityResult = _contentQualityService.CheckOutlineContent(outline);

                if (!qualityResult.IsValid)
                {
                    _logger.LogWarning($"全书大纲质量检查失败: {string.Join(", ", qualityResult.Issues)}");

                    // 尝试使用清理后的内容
                    if (!string.IsNullOrEmpty(qualityResult.CleanedContent) &&
                        qualityResult.CleanedContent.Length > outline.Length * 0.5)
                    {
                        outline = qualityResult.CleanedContent;
                        _logger.LogInformation($"使用清理后的大纲内容");
                    }
                }
                else if (qualityResult.Warnings.Any())
                {
                    _logger.LogInformation($"全书大纲质量警告: {string.Join(", ", qualityResult.Warnings)}");
                }

                // 更新状态
                state.OverallOutline = outline;
                state.OverallOutlineCompleted = true;
                state.LastUpdated = DateTime.Now;

                // 保存到文件
                await SaveOverallOutlineToFileAsync(state, outline);

                result.IsSuccess = true;
                result.Message = "全书大纲生成完成";
                result.Data = outline;
                result.ProgressPercentage = 100;

                _logger.LogInformation($"全书大纲生成完成，项目: {state.BookTitle}");
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation("全书大纲生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"生成全书大纲失败，项目: {state.BookTitle}");
            }

            return result;
        }

        /// <summary>
        /// 步骤2：生成卷宗大纲（支持网络恢复）
        /// </summary>
        public async Task<StepExecutionResult> GenerateVolumeOutlinesAsync(
            StepExecutionState state,
            IProgress<int>? progressCallback = null,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();

            try
            {
                if (!state.OverallOutlineCompleted || string.IsNullOrEmpty(state.OverallOutline))
                {
                    result.IsSuccess = false;
                    result.Message = "请先完成全书大纲生成";
                    return result;
                }

                _logger.LogInformation($"开始生成卷宗大纲，项目: {state.BookTitle}，卷数: {state.VolumeCount}");

                // 生成卷宗大纲，支持网络重试
                List<VolumeOutline> volumeOutlines;
                if (_networkRecovery != null)
                {
                    volumeOutlines = await _networkRecovery.ExecuteWithNetworkRetryAsync(
                        async () => await _novelCreationService.GenerateVolumeOutlinesAsync(
                            state.NovelProjectId, state.OverallOutline, state.VolumeCount),
                        maxRetries: 5,
                        networkRecoveryTimeout: TimeSpan.FromMinutes(15),
                        cancellationToken);
                }
                else
                {
                    volumeOutlines = await _novelCreationService.GenerateVolumeOutlinesAsync(
                        state.NovelProjectId, state.OverallOutline, state.VolumeCount);
                }

                cancellationToken.ThrowIfCancellationRequested();

                // 更新状态
                state.VolumeOutlines = volumeOutlines;
                state.VolumeOutlinesCompleted = true;
                state.LastUpdated = DateTime.Now;

                // 保存到文件
                await SaveVolumeOutlinesToFileAsync(state, volumeOutlines);

                result.IsSuccess = true;
                result.Message = $"卷宗大纲生成完成，共{volumeOutlines.Count}卷";
                result.Data = volumeOutlines;
                result.ProgressPercentage = 100;

                _logger.LogInformation($"卷宗大纲生成完成，项目: {state.BookTitle}，卷数: {volumeOutlines.Count}");
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation("卷宗大纲生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"生成卷宗大纲失败，项目: {state.BookTitle}");
            }

            return result;
        }

        /// <summary>
        /// 步骤3：生成章节细纲（单卷）
        /// </summary>
        public async Task<StepExecutionResult> GenerateChapterOutlinesForVolumeAsync(
            StepExecutionState state,
            int volumeNumber,
            IProgress<int>? progressCallback = null,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();
            
            try
            {
                if (!state.VolumeOutlinesCompleted || !state.VolumeOutlines.Any())
                {
                    result.IsSuccess = false;
                    result.Message = "请先完成卷宗大纲生成";
                    return result;
                }
                
                var volume = state.VolumeOutlines.FirstOrDefault(v => v.VolumeNumber == volumeNumber);
                if (volume == null)
                {
                    result.IsSuccess = false;
                    result.Message = $"未找到第{volumeNumber}卷的大纲";
                    return result;
                }
                
                _logger.LogInformation($"开始生成第{volumeNumber}卷章节细纲，项目: {state.BookTitle}");
                
                var chaptersInVolume = volume.EndChapter - volume.StartChapter + 1;
                var generatedCount = 0;
                
                for (int chapterNum = volume.StartChapter; chapterNum <= volume.EndChapter; chapterNum++)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    // 生成章节细纲，支持网络重试
                    string chapterOutline;
                    if (_networkRecovery != null)
                    {
                        chapterOutline = await _networkRecovery.ExecuteWithNetworkRetryAsync(
                            async () => await GenerateChapterOutlineAsync(state, chapterNum, volume),
                            maxRetries: 3,
                            networkRecoveryTimeout: TimeSpan.FromMinutes(5),
                            cancellationToken);
                    }
                    else
                    {
                        chapterOutline = await GenerateChapterOutlineAsync(state, chapterNum, volume);
                    }

                    // 保存章节细纲
                    state.ChapterOutlines[chapterNum] = chapterOutline;

                    // 提取章节标题
                    var extractedTitle = ExtractChapterTitleFromOutline(chapterOutline, chapterNum);
                    if (!string.IsNullOrEmpty(extractedTitle))
                    {
                        state.ChapterTitles[chapterNum] = extractedTitle;
                        _logger.LogInformation($"第{chapterNum}章标题已提取: {extractedTitle}");
                    }

                    await SaveChapterOutlineToFileAsync(state, chapterNum, chapterOutline);

                    generatedCount++;
                    var progress = (int)((double)generatedCount / chaptersInVolume * 100);
                    progressCallback?.Report(progress);

                    // 避免API限制
                    await Task.Delay(1000, cancellationToken);
                }
                
                state.CurrentVolume = volumeNumber;
                state.LastUpdated = DateTime.Now;
                
                result.IsSuccess = true;
                result.Message = $"第{volumeNumber}卷章节细纲生成完成，共{generatedCount}章";
                result.Data = generatedCount;
                result.ProgressPercentage = 100;
                
                _logger.LogInformation($"第{volumeNumber}卷章节细纲生成完成，项目: {state.BookTitle}，章数: {generatedCount}");
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation($"第{volumeNumber}卷章节细纲生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"生成第{volumeNumber}卷章节细纲失败，项目: {state.BookTitle}");
            }
            
            return result;
        }

        /// <summary>
        /// 步骤4：生成增强章节正文（使用新的增强流程）
        /// </summary>
        public async Task<StepExecutionResult> GenerateEnhancedChapterContentAsync(
            StepExecutionState state,
            int chapterNumber,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();

            try
            {
                if (!state.ChapterOutlines.ContainsKey(chapterNumber))
                {
                    result.IsSuccess = false;
                    result.Message = $"请先生成第{chapterNumber}章的细纲";
                    return result;
                }

                _logger.LogInformation($"开始生成增强第{chapterNumber}章正文，项目: {state.BookTitle}");

                // 使用增强章节内容服务
                if (_enhancedChapterContentService != null)
                {
                    var request = new EnhancedChapterRequest
                    {
                        ProjectId = state.NovelProjectId,
                        ProjectPath = state.ProjectPath,
                        ChapterNumber = chapterNumber,
                        ChapterOutline = state.ChapterOutlines[chapterNumber],
                        TargetWordCount = state.WordsPerChapter,
                        BookTitle = state.BookTitle,
                        CreativeDirection = state.CreativeDirection ?? ""
                    };

                    var enhancedResult = await _enhancedChapterContentService.GenerateEnhancedChapterContentAsync(
                        request, cancellationToken);

                    if (enhancedResult.IsSuccess)
                    {
                        // 保存章节正文
                        state.ChapterContents[chapterNumber] = enhancedResult.Content;
                        await SaveChapterContentToFileAsync(state, chapterNumber, enhancedResult.Content);

                        // 执行后处理流程
                        await PostProcessChapterAsync(state, chapterNumber, enhancedResult.Content);

                        result.IsSuccess = true;
                        result.Message = $"第{chapterNumber}章增强正文生成完成";
                        result.Data = enhancedResult.Content;
                        result.ProgressPercentage = 100;

                        _logger.LogInformation($"第{chapterNumber}章增强正文生成完成，项目: {state.BookTitle}");
                    }
                    else
                    {
                        result.IsSuccess = false;
                        result.Message = $"增强正文生成失败: {enhancedResult.ErrorMessage}";
                        result.ErrorDetails = enhancedResult.ErrorMessage;
                    }
                }
                else
                {
                    // 回退到原有方法
                    return await GenerateChapterContentAsync(state, chapterNumber, cancellationToken);
                }
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation($"第{chapterNumber}章增强正文生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"生成第{chapterNumber}章增强正文失败，项目: {state.BookTitle}");
            }

            return result;
        }

        /// <summary>
        /// 步骤4：生成章节正文（单章）- 原有方法
        /// </summary>
        public async Task<StepExecutionResult> GenerateChapterContentAsync(
            StepExecutionState state,
            int chapterNumber,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();

            try
            {
                if (!state.ChapterOutlines.ContainsKey(chapterNumber))
                {
                    result.IsSuccess = false;
                    result.Message = $"请先生成第{chapterNumber}章的细纲";
                    return result;
                }

                _logger.LogInformation($"开始生成第{chapterNumber}章正文，项目: {state.BookTitle}");

                // 检查章节细纲是否存在
                if (!state.ChapterOutlines.ContainsKey(chapterNumber))
                {
                    throw new InvalidOperationException($"第{chapterNumber}章的细纲不存在，请先生成章节细纲");
                }

                var chapterOutline = state.ChapterOutlines[chapterNumber];
                if (string.IsNullOrEmpty(chapterOutline))
                {
                    throw new InvalidOperationException($"第{chapterNumber}章的细纲为空，请重新生成章节细纲");
                }

                // 确保章节生成前所有必要的世界设定都已生成
                var currentVolume = GetCurrentVolumeForChapter(state, chapterNumber);
                var settingResult = await _enhancedWorldSettingManager.EnsureChapterSettingsCompleteAsync(
                    state.ProjectPath, chapterNumber, state.CreativeDirection ?? "",
                    state.OverallOutline ?? "", currentVolume);

                if (!settingResult.IsComplete)
                {
                    _logger.LogWarning($"第{chapterNumber}章的世界设定不完整，但将继续生成章节内容");
                    if (settingResult.GeneratedSettings.Any())
                    {
                        _logger.LogInformation($"已自动生成设定: {string.Join(", ", settingResult.GeneratedSettings)}");
                    }
                }

                // 获取前文内容作为上下文
                var context = await BuildChapterContextAsync(state, chapterNumber);

                // 检查并补全前一章的结尾（如果存在）
                string previousChapterEnding = string.Empty;
                if (chapterNumber > 1 && state.ChapterContents.ContainsKey(chapterNumber - 1))
                {
                    var previousContent = state.ChapterContents[chapterNumber - 1];

                    // 检查前一章结尾是否完整
                    var endingAnalysis = await _continuityService.AnalyzeChapterEndingAsync(previousContent);
                    if (!endingAnalysis.IsComplete)
                    {
                        _logger.LogInformation($"第{chapterNumber - 1}章结尾不完整，正在补全...");

                        var chapterContext = new ChapterContext
                        {
                            BookTitle = state.BookTitle,
                            ChapterNumber = chapterNumber - 1,
                            TargetWordCount = state.WordsPerChapter,
                            WritingStyle = state.WritingStyle ?? "现代网络小说",
                            CreativeDirection = state.CreativeDirection ?? ""
                        };

                        var previousOutline = state.ChapterOutlines.GetValueOrDefault(chapterNumber - 1, "");
                        var completedContent = await _continuityService.CompleteChapterEndingAsync(
                            previousContent, previousOutline, chapterContext);

                        // 更新前一章内容
                        state.ChapterContents[chapterNumber - 1] = completedContent;
                        await SaveChapterContentToFileAsync(state, chapterNumber - 1, completedContent);

                        _logger.LogInformation($"第{chapterNumber - 1}章结尾补全完成");
                    }

                    // 获取前一章末尾300字用于衔接
                    previousChapterEnding = _continuityService.GetPreviousChapterEnding(
                        state.ChapterContents[chapterNumber - 1], 300);
                }

                // 生成带有前章衔接的章节正文
                string chapterContent;
                if (!string.IsNullOrEmpty(previousChapterEnding))
                {
                    _logger.LogInformation($"使用前章衔接生成第{chapterNumber}章内容");

                    var chapterContext = new ChapterContext
                    {
                        BookTitle = state.BookTitle,
                        ChapterNumber = chapterNumber,
                        TargetWordCount = state.WordsPerChapter,
                        WritingStyle = state.WritingStyle ?? "现代网络小说",
                        CreativeDirection = state.CreativeDirection ?? ""
                    };

                    if (_networkRecovery != null)
                    {
                        chapterContent = await _networkRecovery.ExecuteWithNetworkRetryAsync(
                            async () => await _continuityService.GenerateChapterWithContinuityAsync(
                                chapterOutline, previousChapterEnding, chapterContext, state.WordsPerChapter),
                            maxRetries: 5,
                            networkRecoveryTimeout: TimeSpan.FromMinutes(15),
                            cancellationToken);
                    }
                    else
                    {
                        chapterContent = await _continuityService.GenerateChapterWithContinuityAsync(
                            chapterOutline, previousChapterEnding, chapterContext, state.WordsPerChapter);
                    }
                }
                else
                {
                    // 第一章或没有前章内容时，使用原有方法
                    if (_networkRecovery != null)
                    {
                        chapterContent = await _networkRecovery.ExecuteWithNetworkRetryAsync(
                            async () => await GenerateChapterWithWordCountValidationAsync(
                                chapterOutline, context, state.WordsPerChapter, cancellationToken),
                            maxRetries: 5,
                            networkRecoveryTimeout: TimeSpan.FromMinutes(15),
                            cancellationToken);
                    }
                    else
                    {
                        chapterContent = await GenerateChapterWithWordCountValidationAsync(
                            chapterOutline, context, state.WordsPerChapter, cancellationToken);
                    }
                }

                cancellationToken.ThrowIfCancellationRequested();

                // 进行内容质量检查
                var qualityResult = _contentQualityService.CheckChapterContent(chapterContent, state.WordsPerChapter);

                if (!qualityResult.IsValid)
                {
                    _logger.LogWarning($"第{chapterNumber}章内容质量检查失败: {string.Join(", ", qualityResult.Issues)}");

                    // 尝试使用清理后的内容
                    if (!string.IsNullOrEmpty(qualityResult.CleanedContent) &&
                        qualityResult.CleanedContent.Length > chapterContent.Length * 0.5)
                    {
                        chapterContent = qualityResult.CleanedContent;
                        _logger.LogInformation($"使用清理后的内容，字数: {qualityResult.WordCount}");
                    }
                    else
                    {
                        // 如果清理后的内容太少，记录警告但继续使用原内容
                        _logger.LogWarning($"清理后的内容过少，继续使用原内容");
                    }
                }
                else if (qualityResult.Warnings.Any())
                {
                    _logger.LogInformation($"第{chapterNumber}章内容质量警告: {string.Join(", ", qualityResult.Warnings)}");
                }

                // 保存章节正文
                state.ChapterContents[chapterNumber] = chapterContent;
                await SaveChapterContentToFileAsync(state, chapterNumber, chapterContent);

                // 更新章节细纲（基于生成的正文）
                await UpdateChapterOutlineAfterContentAsync(state, chapterNumber, chapterContent);

                state.CurrentChapter = chapterNumber;
                state.LastUpdated = DateTime.Now;

                result.IsSuccess = true;
                result.Message = $"第{chapterNumber}章正文生成完成";
                result.Data = chapterContent;
                result.ProgressPercentage = 100;

                _logger.LogInformation($"第{chapterNumber}章正文生成完成，项目: {state.BookTitle}");
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation($"第{chapterNumber}章正文生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"生成第{chapterNumber}章正文失败，项目: {state.BookTitle}");
            }

            return result;
        }

        /// <summary>
        /// 新增：逐章生成模式 - 生成单章细纲、正文并更新时间线
        /// </summary>
        public async Task<StepExecutionResult> GenerateChapterSequentiallyAsync(
            StepExecutionState state,
            int chapterNumber,
            IProgress<int>? progressCallback = null,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();

            try
            {
                _logger.LogInformation($"开始逐章生成第{chapterNumber}章，项目: {state.BookTitle}");

                // 步骤1：生成章节细纲
                progressCallback?.Report(10);
                var outlineResult = await GenerateSingleChapterOutlineAsync(state, chapterNumber, cancellationToken);
                if (!outlineResult.IsSuccess)
                {
                    result.IsSuccess = false;
                    result.Message = $"生成第{chapterNumber}章细纲失败: {outlineResult.Message}";
                    return result;
                }

                // 步骤2：生成章节正文（使用增强流程）
                progressCallback?.Report(50);
                var contentResult = await GenerateEnhancedChapterContentAsync(state, chapterNumber, cancellationToken);
                if (!contentResult.IsSuccess)
                {
                    result.IsSuccess = false;
                    result.Message = $"生成第{chapterNumber}章正文失败: {contentResult.Message}";
                    return result;
                }

                // 步骤3：更新时间线
                progressCallback?.Report(80);
                await UpdateTimelineAfterChapterAsync(state, chapterNumber);

                // 步骤4：调整下一章细纲（如果存在）
                progressCallback?.Report(90);
                if (chapterNumber < state.ChapterCount)
                {
                    await PrepareNextChapterOutlineAsync(state, chapterNumber);
                }

                progressCallback?.Report(100);

                result.IsSuccess = true;
                result.Message = $"第{chapterNumber}章逐章生成完成";
                result.Data = contentResult.Data;
                result.ProgressPercentage = 100;

                _logger.LogInformation($"第{chapterNumber}章逐章生成完成，项目: {state.BookTitle}");
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation($"第{chapterNumber}章逐章生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"第{chapterNumber}章逐章生成失败，项目: {state.BookTitle}");
            }

            return result;
        }

        /// <summary>
        /// 新增：生成单章细纲
        /// </summary>
        public async Task<StepExecutionResult> GenerateSingleChapterOutlineAsync(
            StepExecutionState state,
            int chapterNumber,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();

            try
            {
                _logger.LogInformation($"开始生成第{chapterNumber}章细纲，项目: {state.BookTitle}");

                // 获取对应的卷宗信息
                var volume = state.VolumeOutlines.FirstOrDefault(v =>
                    chapterNumber >= v.StartChapter && chapterNumber <= v.EndChapter);

                if (volume == null)
                {
                    result.IsSuccess = false;
                    result.Message = $"找不到第{chapterNumber}章对应的卷宗信息";
                    return result;
                }

                // 生成章节细纲
                var chapterOutline = await GenerateChapterOutlineAsync(state, chapterNumber, volume);

                if (string.IsNullOrEmpty(chapterOutline))
                {
                    result.IsSuccess = false;
                    result.Message = $"第{chapterNumber}章细纲生成失败";
                    return result;
                }

                // 保存章节细纲
                state.ChapterOutlines[chapterNumber] = chapterOutline;

                // 提取章节标题
                var extractedTitle = ExtractChapterTitleFromOutline(chapterOutline, chapterNumber);
                if (!string.IsNullOrEmpty(extractedTitle))
                {
                    state.ChapterTitles[chapterNumber] = extractedTitle;
                    _logger.LogInformation($"第{chapterNumber}章标题已提取: {extractedTitle}");
                }

                await SaveChapterOutlineToFileAsync(state, chapterNumber, chapterOutline);

                result.IsSuccess = true;
                result.Message = $"第{chapterNumber}章细纲生成完成";
                result.Data = chapterOutline;
                result.ProgressPercentage = 100;

                _logger.LogInformation($"第{chapterNumber}章细纲生成完成，项目: {state.BookTitle}");
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation($"第{chapterNumber}章细纲生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"生成第{chapterNumber}章细纲失败，项目: {state.BookTitle}");
            }

            return result;
        }

        /// <summary>
        /// 生成世界设定
        /// </summary>
        public async Task<StepExecutionResult> GenerateWorldSettingAsync(
            StepExecutionState state,
            CancellationToken cancellationToken = default)
        {
            var result = new StepExecutionResult();

            try
            {
                _logger.LogInformation($"开始生成世界设定，项目: {state.BookTitle}");

                // 生成世界设定，支持网络重试
                WorldSetting worldSetting;
                if (_networkRecovery != null)
                {
                    worldSetting = await _networkRecovery.ExecuteWithNetworkRetryAsync(
                        async () => await _worldSettingService.GenerateWorldSettingAsync(
                            state.NovelProjectId, state.CreativeDirection),
                        maxRetries: 5,
                        networkRecoveryTimeout: TimeSpan.FromMinutes(20),
                        cancellationToken);
                }
                else
                {
                    worldSetting = await _worldSettingService.GenerateWorldSettingAsync(
                        state.NovelProjectId, state.CreativeDirection);
                }

                cancellationToken.ThrowIfCancellationRequested();

                // 保存世界设定
                await _worldSettingService.SaveWorldSettingToProjectAsync(worldSetting, state.ProjectPath);

                // 更新状态
                state.WorldSetting = worldSetting;
                state.WorldSettingCompleted = true;
                state.LastUpdated = DateTime.Now;

                result.IsSuccess = true;
                result.Message = "世界设定生成完成";
                result.Data = worldSetting;
                result.ProgressPercentage = 100;

                _logger.LogInformation($"世界设定生成完成，项目: {state.BookTitle}");
            }
            catch (OperationCanceledException)
            {
                result.IsSuccess = false;
                result.Message = "操作已取消";
                _logger.LogInformation("世界设定生成被取消");
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = GetUserFriendlyErrorMessage(ex);
                result.ErrorDetails = ex.Message;
                _logger.LogError(ex, $"生成世界设定失败，项目: {state.BookTitle}");
            }

            return result;
        }

        /// <summary>
        /// 保存执行状态到文件
        /// </summary>
        public async Task SaveStateAsync(StepExecutionState state)
        {
            try
            {
                var stateFilePath = Path.Combine(state.ProjectPath, "step_execution_state.json");
                var json = JsonSerializer.Serialize(state, new JsonSerializerOptions
                {
                    WriteIndented = true,
                    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                });

                await File.WriteAllTextAsync(stateFilePath, json);
                _logger.LogInformation($"执行状态已保存: {stateFilePath}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存执行状态失败");
            }
        }

        /// <summary>
        /// 从文件加载执行状态
        /// </summary>
        public async Task<StepExecutionState?> LoadStateAsync(string projectPath)
        {
            try
            {
                var stateFilePath = Path.Combine(projectPath, "step_execution_state.json");
                if (!File.Exists(stateFilePath))
                {
                    return null;
                }

                var json = await File.ReadAllTextAsync(stateFilePath);
                var state = JsonSerializer.Deserialize<StepExecutionState>(json);

                _logger.LogInformation($"执行状态已加载: {stateFilePath}");
                return state;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "加载执行状态失败");
                return null;
            }
        }

        /// <summary>
        /// 获取执行状态摘要
        /// </summary>
        public string GetStateSummary(StepExecutionState state)
        {
            var summary = new List<string>();

            if (state.OverallOutlineCompleted)
                summary.Add("✓ 全书大纲");
            else
                summary.Add("○ 全书大纲");

            if (state.VolumeOutlinesCompleted)
                summary.Add($"✓ 卷宗大纲({state.VolumeOutlines.Count}卷)");
            else
                summary.Add("○ 卷宗大纲");

            var chapterOutlineCount = state.ChapterOutlines.Count;
            if (chapterOutlineCount > 0)
                summary.Add($"✓ 章节细纲({chapterOutlineCount}章)");
            else
                summary.Add("○ 章节细纲");

            var chapterContentCount = state.ChapterContents.Count;
            if (chapterContentCount > 0)
                summary.Add($"✓ 章节正文({chapterContentCount}章)");
            else
                summary.Add("○ 章节正文");

            if (state.WorldSettingCompleted)
                summary.Add("✓ 世界设定");
            else
                summary.Add("○ 世界设定");

            return string.Join(" | ", summary);
        }

        // 私有辅助方法
        private async Task SaveOverallOutlineToFileAsync(StepExecutionState state, string outline)
        {
            try
            {
                var outlineDir = Path.Combine(state.ProjectPath, "大纲");
                Directory.CreateDirectory(outlineDir);

                // 使用文件命名服务生成标准化的文件名
                var fileName = _fileNamingService.GenerateOutlineFileName(state.BookTitle, "overall", ".txt");
                var filePath = Path.Combine(outlineDir, fileName);
                await File.WriteAllTextAsync(filePath, outline);

                _logger.LogInformation($"全书大纲已保存: {filePath}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存全书大纲失败");
            }
        }

        private async Task SaveVolumeOutlinesToFileAsync(StepExecutionState state, List<VolumeOutline> volumeOutlines)
        {
            try
            {
                // 简化文件夹结构：直接保存在大纲文件夹下，不创建子文件夹
                var outlineDir = Path.Combine(state.ProjectPath, "大纲");
                Directory.CreateDirectory(outlineDir);

                foreach (var volume in volumeOutlines)
                {
                    // 使用文件命名服务生成标准化的文件名，文件名中包含"分卷大纲"标识
                    var fileName = $"{_fileNamingService.SanitizeFileName(state.BookTitle)}_第{volume.VolumeNumber:D2}卷_{_fileNamingService.SanitizeFileName(volume.Title)}_分卷大纲.txt";
                    var filePath = Path.Combine(outlineDir, fileName);
                    var content = $"第{volume.VolumeNumber}卷：{volume.Title}\n\n{volume.Description}";
                    await File.WriteAllTextAsync(filePath, content);
                }

                _logger.LogInformation($"卷宗大纲已保存: {outlineDir}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存卷宗大纲失败");
            }
        }

        private async Task SaveChapterOutlineToFileAsync(StepExecutionState state, int chapterNumber, string outline)
        {
            try
            {
                // 简化文件夹结构：直接保存在大纲文件夹下，不创建子文件夹
                var outlineDir = Path.Combine(state.ProjectPath, "大纲");
                Directory.CreateDirectory(outlineDir);

                // 获取章节标题
                var chapterTitle = state.ChapterTitles.ContainsKey(chapterNumber)
                    ? state.ChapterTitles[chapterNumber]
                    : $"第{chapterNumber}章";

                // 使用文件命名服务生成标准化的文件名，文件名中包含"章节细纲"标识
                var fileName = $"{_fileNamingService.SanitizeFileName(state.BookTitle)}_第{chapterNumber:D3}章_{_fileNamingService.SanitizeFileName(chapterTitle)}_章节细纲.txt";
                var filePath = Path.Combine(outlineDir, fileName);
                await File.WriteAllTextAsync(filePath, outline);

                _logger.LogDebug($"章节细纲已保存: {filePath}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"保存第{chapterNumber}章细纲失败");
            }
        }

        private async Task SaveChapterContentToFileAsync(StepExecutionState state, int chapterNumber, string content)
        {
            try
            {
                // 获取章节标题，清理重复的章节号信息
                var rawChapterTitle = state.ChapterTitles.ContainsKey(chapterNumber)
                    ? state.ChapterTitles[chapterNumber]
                    : $"第{chapterNumber}章";

                // 清理章节标题中的重复信息（移除"第X章"前缀）
                var chapterTitle = CleanChapterTitle(rawChapterTitle, chapterNumber);

                // 获取卷宗信息
                var volume = state.VolumeOutlines?.FirstOrDefault(v =>
                    chapterNumber >= v.StartChapter && chapterNumber <= v.EndChapter);

                var volumeNumber = volume?.VolumeNumber ?? 1;
                var rawVolumeName = volume?.Title ?? "第一卷";

                // 清理卷宗名称中的重复信息（移除"第X卷"前缀）
                var volumeName = CleanVolumeTitle(rawVolumeName, volumeNumber);

                // 使用统一的章节保存服务
                var saveRequest = new ChapterSaveRequest
                {
                    ProjectPath = state.ProjectPath,
                    BookTitle = state.BookTitle,
                    VolumeNumber = volumeNumber,
                    VolumeName = volumeName,
                    ChapterNumber = chapterNumber,
                    ChapterTitle = chapterTitle,
                    Content = content,
                    FileExtension = ".txt"
                };

                var saveResult = await _chapterSaveService.SaveChapterAsync(saveRequest);
                if (saveResult.IsSuccess)
                {
                    _logger.LogInformation($"章节正文已保存: {saveResult.FilePath}");
                }
                else
                {
                    throw new Exception($"章节保存失败: {saveResult.ErrorMessage}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"保存第{chapterNumber}章正文失败");
                throw;
            }
        }

        /// <summary>
        /// 清理章节标题中的重复信息
        /// </summary>
        private string CleanChapterTitle(string title, int chapterNumber)
        {
            if (string.IsNullOrEmpty(title))
                return $"第{chapterNumber}章";

            // 移除开头的"第X章"格式，更精确的匹配
            var patterns = new[]
            {
                $@"^第{chapterNumber}章[：:\s]*",
                $@"^第\d+章[：:\s]*",
                @"^第\d+章[：:\s]*",
                @"^章节\d+[：:\s]*",
                @"^第\d+节[：:\s]*"
            };

            var cleanTitle = title;
            foreach (var pattern in patterns)
            {
                cleanTitle = System.Text.RegularExpressions.Regex.Replace(cleanTitle, pattern, "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            }

            // 清理多余的空格和标点
            cleanTitle = cleanTitle.Trim().Trim('：', ':', '-', '—', '·');

            // 如果清理后为空或只剩下章节号，返回空字符串让文件命名服务处理
            if (string.IsNullOrEmpty(cleanTitle) || cleanTitle == $"第{chapterNumber}章" || cleanTitle == $"{chapterNumber}")
                return "";

            return cleanTitle;
        }

        /// <summary>
        /// 清理卷宗标题中的重复信息
        /// </summary>
        private string CleanVolumeTitle(string title, int volumeNumber)
        {
            if (string.IsNullOrEmpty(title))
                return "";

            // 移除开头的"第X卷"格式，更精确的匹配
            var patterns = new[]
            {
                $@"^第{volumeNumber}卷[：:\s]*",
                $@"^第\d+卷[：:\s]*",
                @"^第\d+卷[：:\s]*",
                @"^卷\d+[：:\s]*",
                @"^第\d+部[：:\s]*"
            };

            var cleanTitle = title;
            foreach (var pattern in patterns)
            {
                cleanTitle = System.Text.RegularExpressions.Regex.Replace(cleanTitle, pattern, "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            }

            // 清理多余的空格和标点
            cleanTitle = cleanTitle.Trim().Trim('：', ':', '-', '—', '·');

            // 如果清理后为空或只剩下卷号，返回空字符串让文件命名服务处理
            if (string.IsNullOrEmpty(cleanTitle) || cleanTitle == $"第{volumeNumber}卷" || cleanTitle == $"{volumeNumber}")
                return "";

            return cleanTitle;
        }

        private async Task<string> GenerateChapterOutlineAsync(StepExecutionState state, int chapterNumber, VolumeOutline volume)
        {
            // 获取项目路径
            var projectPath = await GetProjectPathAsync(state.NovelProjectId);

            // 读取相关的世界设定文件，但只选择与当前章节最相关的几个
            var worldSettings = await ReadRelevantWorldSettingsForChapterAsync(projectPath, chapterNumber, volume);

            // 获取前几章的细纲作为上下文，但只获取最近的1-2章
            var previousOutlines = GetPreviousChapterOutlines(state, chapterNumber, 2);

            // 获取前一章的结尾内容（逐章生成模式的关键）
            string previousChapterEnding = "";
            if (chapterNumber > 1 && state.ChapterContents.ContainsKey(chapterNumber - 1))
            {
                var previousChapterContent = state.ChapterContents[chapterNumber - 1];
                previousChapterEnding = GetChapterEnding(previousChapterContent);
            }

            // 检查是否是新卷的第一章，如果是，需要参考上一卷的时间线
            string previousVolumeTimeline = "";
            bool isNewVolumeFirstChapter = (chapterNumber == volume.StartChapter && volume.VolumeNumber > 1);

            if (isNewVolumeFirstChapter)
            {
                // 获取上一卷的时间线
                var previousVolumeNumber = volume.VolumeNumber - 1;
                previousVolumeTimeline = await ReadVolumeTimelineByOutlinesAsync(projectPath, previousVolumeNumber, state.VolumeOutlines);

                if (!string.IsNullOrEmpty(previousVolumeTimeline))
                {
                    // 限制时间线长度
                    if (previousVolumeTimeline.Length > 2000)
                    {
                        previousVolumeTimeline = previousVolumeTimeline.Substring(0, 2000) + "...[上一卷时间线已截断]";
                    }
                }
            }

            // 构建聚焦的提示词，强调章节差异化和前文衔接
            var prompt = BuildFocusedChapterOutlinePrompt(state, chapterNumber, volume, worldSettings, previousOutlines, previousChapterEnding, previousVolumeTimeline);

            // 使用较高的temperature增加创意多样性
            return await _aiService.GenerateTextAsync(prompt, 3000, 0.9f);
        }

        /// <summary>
        /// 读取与当前章节最相关的世界设定文件
        /// </summary>
        private async Task<Dictionary<string, string>> ReadRelevantWorldSettingsForChapterAsync(
            string projectPath, int chapterNumber, VolumeOutline volume)
        {
            // 获取所有世界设定
            var allSettings = await ReadRelevantWorldSettingsAsync(projectPath);

            // 确保allSettings不为null
            if (allSettings == null)
            {
                _logger.LogWarning($"读取世界设定失败，返回空字典");
                return new Dictionary<string, string>();
            }

            // 创建结果字典
            var relevantSettings = new Dictionary<string, string>();

            // 始终包含的核心设定
            var alwaysIncluded = new[] { "角色设定管理", "关系网络" };
            foreach (var core in alwaysIncluded)
            {
                if (allSettings.ContainsKey(core))
                {
                    relevantSettings[core] = allSettings[core];
                }
            }

            // 根据章节号和卷宗信息选择额外的相关设定
            // 例如：前期章节关注世界观，中期关注势力冲突，后期关注修炼突破
            bool isEarlyChapter = true;  // 默认为前期章节
            bool isLateChapter = false;

            if (volume != null)
            {
                var volumeLength = volume.EndChapter - volume.StartChapter;
                isEarlyChapter = chapterNumber <= volume.StartChapter + volumeLength / 3;
                isLateChapter = chapterNumber >= volume.EndChapter - volumeLength / 3;
            }
            else
            {
                // 如果没有卷宗信息，根据章节号简单判断
                isEarlyChapter = chapterNumber <= 10;  // 前10章为前期
                isLateChapter = chapterNumber >= 30;   // 30章以后为后期
            }

            if (isEarlyChapter)
            {
                // 前期章节关注世界观和基础设定
                var earlyFocus = new[] { "世界观设定管理", "地图结构管理", "种族类别管理" };
                foreach (var setting in earlyFocus)
                {
                    if (allSettings.ContainsKey(setting))
                    {
                        relevantSettings[setting] = allSettings[setting];
                    }
                }
            }
            else if (isLateChapter)
            {
                // 后期章节关注修炼突破和高级设定
                var lateFocus = new[] { "修炼体系设定管理", "功法体系管理", "灵宝体系管理" };
                foreach (var setting in lateFocus)
                {
                    if (allSettings.ContainsKey(setting))
                    {
                        relevantSettings[setting] = allSettings[setting];
                    }
                }
            }
            else
            {
                // 中期章节关注势力冲突和人物关系
                var midFocus = new[] { "势力管理", "政治体系管理", "时间线管理" };
                foreach (var setting in midFocus)
                {
                    if (allSettings.ContainsKey(setting))
                    {
                        relevantSettings[setting] = allSettings[setting];
                    }
                }
            }

            _logger.LogInformation($"为第{chapterNumber}章选择了{relevantSettings.Count}个相关世界设定文件");
            return relevantSettings;
        }

        /// <summary>
        /// 构建聚焦的章节细纲生成提示词，强调章节差异化
        /// </summary>
        private string BuildFocusedChapterOutlinePrompt(StepExecutionState state, int chapterNumber, VolumeOutline volume,
            Dictionary<string, string> worldSettings, List<string> previousOutlines, string previousChapterEnding = "", string previousVolumeTimeline = "")
        {
            // 确定当前章节在卷中的位置
            int chaptersInVolume = volume.EndChapter - volume.StartChapter + 1;
            int chapterPositionInVolume = chapterNumber - volume.StartChapter + 1;
            double progressPercentage = (double)chapterPositionInVolume / chaptersInVolume;

            // 根据章节在卷中的位置确定剧情发展阶段
            string stageDescription;
            if (progressPercentage <= 0.25)
            {
                stageDescription = "本章处于卷宗前期，应着重铺设背景、引入人物和初步展开冲突";
            }
            else if (progressPercentage <= 0.75)
            {
                stageDescription = "本章处于卷宗中期，应着重发展冲突、深化人物关系和推进主线剧情";
            }
            else
            {
                stageDescription = "本章处于卷宗后期，应着重推向高潮、解决关键冲突并为下一卷做铺垫";
            }

            // 构建精简的世界设定文本，只包含最相关的内容
            var worldSettingsText = "";
            if (worldSettings.Any())
            {
                worldSettingsText = "\n=== 本章相关世界设定（请重点参考）===\n";

                // 限制每个设定文件的内容长度，确保提示词不会过长
                foreach (var setting in worldSettings)
                {
                    // 提取设定文件中的关键信息，而不是全文
                    var content = ExtractKeyInformation(setting.Value, 800);
                    worldSettingsText += $"\n【{setting.Key}】\n{content}\n";
                }
            }

            // 构建前几章细纲参考文本，但更加精简
            var previousOutlinesText = "";
            if (previousOutlines.Any())
            {
                // 只使用最近的一章作为直接参考
                previousOutlinesText = "\n=== 上一章细纲（请确保剧情连贯）===\n";
                previousOutlinesText += previousOutlines.LastOrDefault() ?? "";
            }

            var prompt = $@"你是一位专业的小说创作助手，现在需要为第{chapterNumber}章创作一个独特且引人入胜的章节细纲。

=== 核心任务 ===
为《{state.BookTitle}》第{chapterNumber}章（第{volume.VolumeNumber}卷第{chapterPositionInVolume}章）创作细纲

=== 章节定位 ===
{stageDescription}
当前进度：第{volume.VolumeNumber}卷的第{chapterPositionInVolume}/{chaptersInVolume}章（{progressPercentage:P0}）

=== 卷宗核心任务 ===
{volume.Title}：{volume.Description}

=== 全书主线方向 ===
{GetMainPlotDirection(state.OverallOutline)}
{worldSettingsText}
{previousOutlinesText}

{(string.IsNullOrEmpty(previousChapterEnding) ? "" : $@"
=== 前一章结尾内容（必须自然衔接）===
{previousChapterEnding}
")}

{(string.IsNullOrEmpty(previousVolumeTimeline) ? "" : $@"
=== 上一卷时间线总结（新卷开篇必须参考）===
{previousVolumeTimeline}

注意：本章是第{volume.VolumeNumber}卷的开篇章节，需要承接上一卷的剧情发展，同时开启新卷的故事线。
")}

=== 本章创作要求 ===
请为第{chapterNumber}章创作一个与众不同的细纲，必须做到：
1. 【衔接性】{(string.IsNullOrEmpty(previousChapterEnding) && string.IsNullOrEmpty(previousVolumeTimeline) ? "作为开篇章节，要有引人入胜的开头" :
    !string.IsNullOrEmpty(previousVolumeTimeline) ? "作为新卷开篇，必须承接上一卷的剧情发展，同时开启新的故事线" :
    "必须与前一章结尾自然衔接，承接剧情发展")}
2. 【差异化】与前面章节有明显不同的情节发展和冲突设计
3. 【推进性】明确推进卷宗主线，不能原地踏步
4. 【独特性】本章必须有独特的场景、冲突或人物发展
5. 【爽点设计】设计本章独有的精彩看点和读者期待点
6. 【逻辑性】情节发展要符合逻辑，角色行为要合理
{(!string.IsNullOrEmpty(previousVolumeTimeline) ? "7. 【承启性】作为新卷开篇，要总结前卷成果，预示新卷挑战" : "")}

=== 章节细纲格式 ===
请按照以下格式创作第{chapterNumber}章的细纲：

## 第{chapterNumber}章：[创新性标题，反映本章独特内容]

### 本章核心亮点（必须与前几章有明显区别）
- 独特场景：[本章特有的场景或环境，不可与前几章重复]
- 核心冲突：[本章的主要冲突或挑战，需有新意]
- 人物发展：[角色在本章的成长或变化]
- 读者期待：[读者会特别期待的精彩内容]

### 场景与氛围
- 主要场景：[本章的主要场景，需具体详细]
- 时间点：[在故事时间线上的具体位置]
- 氛围营造：[本章的情绪基调和氛围]

### 人物动态
- 主角表现：[主角在本章的行动和心理]
- 重要角色：[其他重要角色的表现和互动]
- 关系变化：[本章中发生的人物关系变化]

### 剧情发展（必须推进主线）
- 起始情境：[本章开始时的情况，承接上章]
- 情节推进：[本章的主要事件发展]
- 高潮设计：[本章的高潮或转折点]
- 结尾铺垫：[为下一章做的铺垫]

### 世界元素运用
- 设定展现：[本章展现的世界设定元素]
- 伏笔安排：[埋下的伏笔或线索]

### 预期结果
- 情节推进：[对整体故事的推进作用，与大纲的对应关系]
- 角色成长：[角色的变化和成长，修炼进展等]
- 伏笔铺设：[为后续章节埋下的伏笔]
- 章节结尾：[本章的结束方式和过渡]

请确保细纲详细具体，充分体现世界观设定的丰富性，避免剧情重复，为后续正文创作提供清晰指导。";

            return prompt;
        }

        /// <summary>
        /// 从全书大纲中提取主线方向
        /// </summary>
        private string GetMainPlotDirection(string overallOutline)
        {
            if (string.IsNullOrEmpty(overallOutline))
                return "请参考创作方向推进主线剧情";

            // 提取大纲中的关键信息，限制长度
            if (overallOutline.Length > 1000)
            {
                return overallOutline.Substring(0, 1000) + "...[主线方向]";
            }
            return overallOutline;
        }

        /// <summary>
        /// 从设定文件中提取关键信息
        /// </summary>
        private string ExtractKeyInformation(string content, int maxLength)
        {
            if (string.IsNullOrEmpty(content))
                return "";

            // 简单的关键信息提取：保留前面的重要内容
            if (content.Length <= maxLength)
                return content;

            // 尝试在句号处截断，保持内容完整性
            var truncated = content.Substring(0, maxLength);
            var lastPeriod = truncated.LastIndexOf('。');
            if (lastPeriod > maxLength * 0.7) // 如果句号位置合理
            {
                return truncated.Substring(0, lastPeriod + 1);
            }

            return truncated + "...";
        }

        private async Task<string> BuildChapterContextAsync(StepExecutionState state, int chapterNumber)
        {
            try
            {
                var context = new List<string>();

                // 添加全书大纲（简化版）
                if (!string.IsNullOrEmpty(state.OverallOutline))
                {
                    var outline = state.OverallOutline;
                    if (outline.Length > 800)
                    {
                        outline = outline.Substring(0, 800) + "...[内容已截断]";
                    }
                    context.Add($"全书大纲：{outline}");
                }

                // 获取项目路径并读取最相关的世界设定（最多4个文件）
                var projectPath = await GetProjectPathAsync(state.NovelProjectId);
                if (string.IsNullOrEmpty(projectPath))
                {
                    _logger.LogWarning($"无法获取项目路径，项目ID: {state.NovelProjectId}");
                    return string.Join("\n\n", context);
                }

                // 除第一章外，其余章节都需要参考分卷时间线
                if (chapterNumber > 1)
                {
                    var currentVolumeNumber = GetVolumeNumberByChapter(chapterNumber, state.VolumeOutlines);
                    var volumeTimeline = await ReadVolumeTimelineByOutlinesAsync(projectPath, currentVolumeNumber, state.VolumeOutlines);

                    if (!string.IsNullOrEmpty(volumeTimeline))
                    {
                        // 限制时间线长度，避免上下文过长
                        if (volumeTimeline.Length > 1500)
                        {
                            volumeTimeline = volumeTimeline.Substring(0, 1500) + "...[时间线内容已截断]";
                        }
                        context.Add($"当前卷时间线：\n{volumeTimeline}");
                    }
                }

                var worldSettings = await ReadRelevantWorldSettingsForChapterAsync(projectPath, chapterNumber, null);

            // 添加最相关的世界设定信息（限制数量和长度）
            if (worldSettings.Any())
            {
                var settingsCount = 0;
                var maxSettings = 4; // 最多4个设定文件

                // 优先添加核心设定
                var coreSettings = new[] { "角色设定管理", "关系网络", "世界观设定管理", "修炼体系设定管理" };
                foreach (var coreSetting in coreSettings)
                {
                    if (settingsCount >= maxSettings) break;

                    if (worldSettings.ContainsKey(coreSetting))
                    {
                        var content = worldSettings[coreSetting];
                        if (content.Length > 500) // 进一步缩短
                        {
                            content = content.Substring(0, 500) + "...";
                        }
                        context.Add($"{coreSetting}：{content}");
                        settingsCount++;
                    }
                }
            }

            // 添加前一章的结尾内容（逐章生成模式的关键）
            // 注意：序章也需要参考前一章，确保剧情连贯性
            if (chapterNumber > 1)
            {
                // 优先查找前一章的内容
                var previousChapterNumber = chapterNumber - 1;
                if (state.ChapterContents.ContainsKey(previousChapterNumber))
                {
                    var previousChapterContent = state.ChapterContents[previousChapterNumber];
                    var previousChapterEnding = GetChapterEnding(previousChapterContent);
                    if (!string.IsNullOrEmpty(previousChapterEnding))
                    {
                        context.Add($"【重要】前一章结尾（必须自然衔接）：\n{previousChapterEnding}");
                        _logger.LogInformation($"第{chapterNumber}章已添加前一章结尾上下文，长度: {previousChapterEnding.Length}");
                    }
                    else
                    {
                        _logger.LogWarning($"第{previousChapterNumber}章结尾内容为空，无法为第{chapterNumber}章提供衔接上下文");
                    }
                }
                else
                {
                    _logger.LogWarning($"第{previousChapterNumber}章内容不存在，第{chapterNumber}章无法获得前章衔接上下文");
                }
            }

            // 添加前几章的内容摘要（限制数量和长度）
            var previousChaptersToInclude = Math.Min(2, chapterNumber - 1);
            for (int i = Math.Max(1, chapterNumber - previousChaptersToInclude); i < chapterNumber; i++)
            {
                if (state.ChapterContents.ContainsKey(i))
                {
                    var content = state.ChapterContents[i];
                    // 获取章节开头和结尾的关键部分
                    var summary = GetChapterSummary(content, i);
                    if (!string.IsNullOrEmpty(summary))
                    {
                        context.Add($"第{i}章摘要：{summary}");
                    }
                }
            }

                return string.Join("\n\n", context);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"构建第{chapterNumber}章上下文失败");
                return $"全书大纲：{state.OverallOutline ?? "暂无大纲"}";
            }
        }

        /// <summary>
        /// 获取项目路径
        /// </summary>
        private async Task<string> GetProjectPathAsync(int novelProjectId)
        {
            try
            {
                var novelProject = await _dataStorage.GetNovelProjectAsync(novelProjectId);
                if (novelProject != null)
                {
                    // 通过 ProjectId 获取基础项目信息
                    var project = await _dataStorage.GetProjectAsync(novelProject.ProjectId);
                    if (project != null && !string.IsNullOrEmpty(project.RootPath))
                    {
                        return project.RootPath;
                    }
                }

                // 如果没有设置项目路径，使用默认路径
                var defaultPath = Path.Combine(Environment.CurrentDirectory, "Projects", $"Project_{novelProjectId}");
                if (!Directory.Exists(defaultPath))
                {
                    Directory.CreateDirectory(defaultPath);
                }
                return defaultPath;
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, $"获取项目路径失败，使用默认路径");
                var defaultPath = Path.Combine(Environment.CurrentDirectory, "Projects", $"Project_{novelProjectId}");
                if (!Directory.Exists(defaultPath))
                {
                    Directory.CreateDirectory(defaultPath);
                }
                return defaultPath;
            }
        }

        /// <summary>
        /// 读取相关的世界设定文件
        /// </summary>
        private async Task<Dictionary<string, string>> ReadRelevantWorldSettingsAsync(string projectPath)
        {
            var worldSettings = new Dictionary<string, string>();

            // 世界观设定管理文件列表
            var worldSettingFiles = new List<string>
            {
                "世界观设定管理.md", "维度结构管理.md", "地图结构管理.md", "秘境管理.md", "时间线管理.md",
                "剧情大纲设定管理.md", "角色设定管理.md", "关系网络.md", "种族类别管理.md", "修炼体系设定管理.md",
                "功法体系管理.md", "武器管理.md", "灵宝体系管理.md", "装备体系管理.md", "势力管理.md",
                "政治体系管理.md", "司法体系管理.md", "商业体系管理.md", "职业体系管理.md", "货币体系管理.md",
                "资源管理.md", "宠物体系管理.md", "生民体系管理.md"
            };

            _logger.LogInformation($"开始读取世界设定文件，项目路径: {projectPath}");
            var settingsPath = Path.Combine(projectPath, "设定");

            try
            {
                var loadedCount = 0;
                var totalSize = 0;

                foreach (var fileName in worldSettingFiles)
                {
                    // 首先检查设定文件夹中的文件
                    var filePath = Path.Combine(settingsPath, fileName);
                    if (!File.Exists(filePath))
                    {
                        // 如果设定文件夹中没有，检查项目根目录
                        filePath = Path.Combine(projectPath, fileName);
                    }

                    if (File.Exists(filePath))
                    {
                        var content = await File.ReadAllTextAsync(filePath, Encoding.UTF8);
                        if (!string.IsNullOrWhiteSpace(content))
                        {
                            // 清理内容，移除多余的空行和格式字符
                            content = content.Trim();

                            // 限制每个文件内容长度，避免提示词过长
                            if (content.Length > 3000)
                            {
                                content = content.Substring(0, 3000) + "\n...[内容已截断]";
                            }

                            worldSettings[fileName.Replace(".md", "")] = content;
                            loadedCount++;
                            totalSize += content.Length;

                            _logger.LogDebug($"已加载世界设定文件: {fileName}, 大小: {content.Length}字符");
                        }
                        else
                        {
                            _logger.LogDebug($"世界设定文件为空: {fileName}");
                        }
                    }
                    else
                    {
                        _logger.LogDebug($"世界设定文件不存在: {fileName}");
                    }
                }

                _logger.LogInformation($"世界设定文件加载完成，共加载{loadedCount}个文件，总大小{totalSize}字符");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "读取世界设定文件失败");
            }

            return worldSettings;
        }

        /// <summary>
        /// 获取前几章的细纲作为参考
        /// </summary>
        private List<string> GetPreviousChapterOutlines(StepExecutionState state, int chapterNumber, int count)
        {
            var previousOutlines = new List<string>();

            try
            {
                for (int i = Math.Max(1, chapterNumber - count); i < chapterNumber; i++)
                {
                    if (state.ChapterOutlines.ContainsKey(i))
                    {
                        var outline = state.ChapterOutlines[i];
                        if (!string.IsNullOrWhiteSpace(outline))
                        {
                            // 提取章节标题和主要内容
                            var lines = outline.Split('\n');
                            var title = lines.FirstOrDefault(l => l.StartsWith("## 第") || l.StartsWith("#")) ?? $"第{i}章";
                            var summary = outline.Length > 500 ? outline.Substring(0, 500) + "..." : outline;
                            previousOutlines.Add($"{title}\n{summary}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "获取前几章细纲时出错");
            }

            return previousOutlines;
        }

        private async Task UpdateChapterOutlineAfterContentAsync(StepExecutionState state, int chapterNumber, string content)
        {
            try
            {
                // 基于生成的正文更新下一章的细纲（如果存在）
                var nextChapter = chapterNumber + 1;
                if (state.ChapterOutlines.ContainsKey(nextChapter))
                {
                    var currentOutline = state.ChapterOutlines[nextChapter];

                    // 获取项目路径和世界设定
                    var projectPath = await GetProjectPathAsync(state.NovelProjectId);
                    var worldSettings = await ReadRelevantWorldSettingsAsync(projectPath);

                    // 获取相关卷宗信息
                    var relevantVolume = state.VolumeOutlines.FirstOrDefault(v =>
                        nextChapter >= v.StartChapter && nextChapter <= v.EndChapter);

                    var worldSettingsText = "";
                    if (worldSettings.Any())
                    {
                        worldSettingsText = "\n=== 相关世界设定 ===\n";

                        // 优先添加核心设定文件
                        var coreSettings = new[] { "角色设定管理", "关系网络", "时间线管理", "剧情大纲设定管理" };
                        foreach (var coreSetting in coreSettings)
                        {
                            if (worldSettings.ContainsKey(coreSetting))
                            {
                                var settingContent = worldSettings[coreSetting];
                                if (settingContent.Length > 1000)
                                {
                                    settingContent = settingContent.Substring(0, 1000) + "...[内容已截断]";
                                }
                                worldSettingsText += $"\n【{coreSetting}】\n{settingContent}\n";
                            }
                        }

                        // 添加其他相关设定（限制数量）
                        foreach (var setting in worldSettings.Where(s => !coreSettings.Contains(s.Key)).Take(3))
                        {
                            var settingContent = setting.Value;
                            if (settingContent.Length > 800)
                            {
                                settingContent = settingContent.Substring(0, 800) + "...[内容已截断]";
                            }
                            worldSettingsText += $"\n【{setting.Key}】\n{settingContent}\n";
                        }
                    }

                    var updatePrompt = $@"请基于前一章的实际内容和世界设定更新下一章的细纲：

=== 前一章实际内容 ===
第{chapterNumber}章内容：
{content.Substring(0, Math.Min(content.Length, 1000))}...

=== 全书大纲 ===
{state.OverallOutline}

{(relevantVolume != null ? $@"=== 当前卷宗大纲 ===
第{relevantVolume.VolumeNumber}卷 - {relevantVolume.Title}
{relevantVolume.Description}
" : "")}

=== 当前第{nextChapter}章细纲 ===
{currentOutline}
{worldSettingsText}

=== 更新要求 ===
请更新第{nextChapter}章细纲，确保：
1. 与前一章的结尾自然衔接，承接剧情发展
2. 严格遵循全书大纲和卷宗大纲的设定
3. 充分利用世界观设定中的元素
4. 保持故事的连贯性和逻辑性
5. 调整不合理的情节设置
6. 避免与前文重复的剧情内容
7. 保持原有的主要情节方向和目标

请返回更新后的完整章节细纲，格式与原细纲保持一致。";

                    var updatedOutline = await _aiService.GenerateTextAsync(updatePrompt, 2000, 0.7f);
                    state.ChapterOutlines[nextChapter] = updatedOutline;

                    // 保存更新后的细纲
                    await SaveChapterOutlineToFileAsync(state, nextChapter, updatedOutline);

                    _logger.LogInformation($"已更新第{nextChapter}章细纲");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新第{chapterNumber + 1}章细纲失败");
            }
        }

        /// <summary>
        /// 获取用户友好的错误消息
        /// </summary>
        private string GetUserFriendlyErrorMessage(Exception ex)
        {
            var message = ex.Message;

            // LM Studio连接错误
            if (message.Contains("BadGateway") || message.Contains("502"))
            {
                return "LM Studio服务器错误，可能是模型负载过高。建议：重启LM Studio并重新加载模型，或尝试使用较小的模型";
            }

            // AI服务不可用错误
            if (message.Contains("AI服务暂时不可用") || message.Contains("没有可用的AI服务提供者"))
            {
                return "AI服务暂时不可用，请检查AI模型配置或稍后重试。建议：确认LM Studio正在运行并已加载模型";
            }

            // 网络相关错误
            if (message.Contains("SSL connection") ||
                message.Contains("远程主机强迫关闭") ||
                message.Contains("connection") ||
                ex is HttpRequestException)
            {
                return "网络连接异常，请检查网络状态和LM Studio服务状态。系统会自动重试，请稍候...";
            }

            // 超时错误
            if (ex is TaskCanceledException || message.Contains("timeout"))
            {
                return "请求超时，可能是模型生成时间过长。建议：检查模型负载情况，或尝试减少生成字数";
            }

            // 章节生成相关错误
            if (message.Contains("章节生成失败"))
            {
                return "章节内容生成失败，可能是模型配置问题。建议：检查MaxTokens设置，确保足够生成长文本";
            }

            // AI服务错误
            if (message.Contains("智谱AI") || message.Contains("DeepSeek") ||
                message.Contains("API") || message.Contains("模型"))
            {
                return "AI服务暂时不可用，请检查AI模型配置或稍后重试";
            }

            // 文件操作错误
            if (ex is IOException || message.Contains("文件") || message.Contains("路径"))
            {
                return "文件操作失败，请检查项目文件夹权限";
            }

            // 默认错误消息
            return "操作失败，请稍后重试";
        }

        /// <summary>
        /// 检查网络状态并提供用户提示
        /// </summary>
        public async Task<string> GetNetworkStatusMessageAsync()
        {
            if (_networkRecovery != null)
            {
                return await _networkRecovery.GetNetworkStatusAsync();
            }
            return "网络状态检查服务不可用";
        }

        /// <summary>
        /// 获取可恢复任务列表
        /// </summary>
        public async Task<List<ResumableCreationService.CreationTaskState>> GetResumableTasksAsync(string projectPath)
        {
            if (_resumableCreation != null)
            {
                return await _resumableCreation.GetProjectTaskStatesAsync(projectPath);
            }
            return new List<ResumableCreationService.CreationTaskState>();
        }

        /// <summary>
        /// 清理过期的任务状态
        /// </summary>
        public async Task CleanupOldTaskStatesAsync(string projectPath)
        {
            if (_resumableCreation != null)
            {
                await _resumableCreation.CleanupCompletedTasksAsync(projectPath);
            }
        }

        /// <summary>
        /// 从章节细纲中提取章节标题
        /// </summary>
        private string ExtractChapterTitleFromOutline(string outline, int chapterNumber)
        {
            try
            {
                if (string.IsNullOrEmpty(outline))
                {
                    return $"第{chapterNumber}章";
                }

                // 查找章节标题的多种可能格式
                var patterns = new[]
                {
                    $@"##\s*第{chapterNumber}章[：:]\s*(.+?)(?:\n|$)",  // ## 第X章：标题
                    $@"第{chapterNumber}章[：:]\s*(.+?)(?:\n|$)",       // 第X章：标题
                    $@"##\s*第{chapterNumber}章\s+(.+?)(?:\n|$)",      // ## 第X章 标题
                    $@"第{chapterNumber}章\s+(.+?)(?:\n|$)"            // 第X章 标题
                };

                foreach (var pattern in patterns)
                {
                    var match = System.Text.RegularExpressions.Regex.Match(outline, pattern,
                        System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                        System.Text.RegularExpressions.RegexOptions.Multiline);

                    if (match.Success && match.Groups.Count > 1)
                    {
                        var title = match.Groups[1].Value.Trim();

                        // 清理标题中的特殊字符和格式标记
                        title = title.Replace("[", "").Replace("]", "")
                                   .Replace("【", "").Replace("】", "")
                                   .Replace("（", "").Replace("）", "")
                                   .Replace("(", "").Replace(")", "")
                                   .Trim();

                        // 如果标题不为空且不是占位符，返回完整标题
                        if (!string.IsNullOrEmpty(title) &&
                            !title.Contains("章节标题") &&
                            !title.Contains("标题") &&
                            title.Length > 1)
                        {
                            return $"第{chapterNumber}章_{title}";
                        }
                    }
                }

                // 默认返回章节号
                return $"第{chapterNumber}章";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"提取第{chapterNumber}章标题失败");
                return $"第{chapterNumber}章";
            }
        }

        /// <summary>
        /// 清理文件名中的非法字符
        /// </summary>
        private string SanitizeFileName(string fileName)
        {
            var invalidChars = Path.GetInvalidFileNameChars();
            var sanitized = fileName;

            foreach (var invalidChar in invalidChars)
            {
                sanitized = sanitized.Replace(invalidChar, '_');
            }

            // 替换一些常见的特殊字符
            sanitized = sanitized.Replace(":", "：")
                                 .Replace("?", "？")
                                 .Replace("*", "＊")
                                 .Replace("<", "＜")
                                 .Replace(">", "＞")
                                 .Replace("|", "｜")
                                 .Replace("\"", "\"")
                                 .Replace("/", "／")
                                 .Replace("\\", "＼");

            return sanitized.Trim();
        }

        /// <summary>
        /// 新增：更新时间线（逐章生成模式专用）
        /// </summary>
        private async Task UpdateTimelineAfterChapterAsync(StepExecutionState state, int chapterNumber)
        {
            try
            {
                if (state == null || !state.ChapterContents.ContainsKey(chapterNumber))
                    return;

                var chapterContent = state.ChapterContents[chapterNumber];
                var projectPath = await GetProjectPathAsync(state.NovelProjectId);

                if (string.IsNullOrEmpty(projectPath))
                {
                    _logger.LogWarning($"无法获取项目路径，跳过时间线更新，章节: {chapterNumber}");
                    return;
                }

                // 更新时间线文件
                var timelinePath = Path.Combine(projectPath, "设定", "时间线管理.md");

                // 确保目录存在
                Directory.CreateDirectory(Path.GetDirectoryName(timelinePath));

                // 读取现有时间线
                string existingTimeline = "";
                if (File.Exists(timelinePath))
                {
                    existingTimeline = await File.ReadAllTextAsync(timelinePath);
                }

                // 生成章节时间线摘要
                var timelineSummary = await GenerateChapterTimelineSummaryAsync(chapterNumber, chapterContent);

                // 更新时间线内容
                var updatedTimeline = UpdateTimelineContent(existingTimeline, chapterNumber, timelineSummary);

                // 保存更新后的时间线
                await File.WriteAllTextAsync(timelinePath, updatedTimeline);

                _logger.LogInformation($"第{chapterNumber}章时间线更新完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新第{chapterNumber}章时间线失败");
            }
        }

        /// <summary>
        /// 新增：为下一章准备细纲（基于当前章节的结尾）
        /// </summary>
        private async Task PrepareNextChapterOutlineAsync(StepExecutionState state, int currentChapterNumber)
        {
            try
            {
                var nextChapterNumber = currentChapterNumber + 1;

                // 检查下一章是否在合理范围内
                if (nextChapterNumber > state.ChapterCount)
                    return;

                // 获取当前章节的结尾内容（用于衔接）
                if (!state.ChapterContents.ContainsKey(currentChapterNumber))
                    return;

                var currentChapterContent = state.ChapterContents[currentChapterNumber];
                var chapterEnding = GetChapterEnding(currentChapterContent);

                // 获取下一章对应的卷宗信息
                var nextVolume = state.VolumeOutlines.FirstOrDefault(v =>
                    nextChapterNumber >= v.StartChapter && nextChapterNumber <= v.EndChapter);

                if (nextVolume == null)
                {
                    _logger.LogWarning($"找不到第{nextChapterNumber}章对应的卷宗信息");
                    return;
                }

                // 预生成下一章的细纲（为后续生成做准备）
                var nextChapterOutline = await GenerateNextChapterOutlineWithContextAsync(
                    state, nextChapterNumber, nextVolume, chapterEnding);

                if (!string.IsNullOrEmpty(nextChapterOutline))
                {
                    state.ChapterOutlines[nextChapterNumber] = nextChapterOutline;

                    // 提取章节标题
                    var extractedTitle = ExtractChapterTitleFromOutline(nextChapterOutline, nextChapterNumber);
                    if (!string.IsNullOrEmpty(extractedTitle))
                    {
                        state.ChapterTitles[nextChapterNumber] = extractedTitle;
                    }

                    await SaveChapterOutlineToFileAsync(state, nextChapterNumber, nextChapterOutline);
                    _logger.LogInformation($"已为第{nextChapterNumber}章预生成细纲");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"为第{currentChapterNumber + 1}章准备细纲失败");
            }
        }

        /// <summary>
        /// 新增：生成章节时间线摘要
        /// </summary>
        private async Task<string> GenerateChapterTimelineSummaryAsync(int chapterNumber, string chapterContent)
        {
            try
            {
                var prompt = $@"
请基于以下第{chapterNumber}章的内容，生成简洁的时间线摘要：

=== 章节内容 ===
{chapterContent.Substring(0, Math.Min(chapterContent.Length, 2000))}...

=== 要求 ===
请提取本章的关键事件和时间线信息，格式如下：
- 时间：[具体时间或时间段]
- 地点：[主要场景]
- 主要事件：[核心情节]
- 角色状态：[主要角色的变化]
- 重要结果：[对后续剧情的影响]

请保持简洁，每项不超过50字。";

                return await _aiService.GenerateTextAsync(prompt, 500, 0.7f);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"生成第{chapterNumber}章时间线摘要失败");
                return $"第{chapterNumber}章 - 时间线摘要生成失败";
            }
        }

        /// <summary>
        /// 新增：获取章节结尾内容
        /// </summary>
        private string GetChapterEnding(string chapterContent)
        {
            if (string.IsNullOrEmpty(chapterContent))
                return "";

            // 清理内容，移除多余的空行和格式
            var cleanContent = chapterContent.Trim();

            // 获取章节的最后800字作为结尾（增加长度以提供更好的上下文）
            var endingLength = Math.Min(800, cleanContent.Length);
            var startIndex = Math.Max(0, cleanContent.Length - endingLength);

            var ending = cleanContent.Substring(startIndex);

            // 尝试从完整句子开始
            var sentences = ending.Split(new char[] { '。', '！', '？', '.', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
            if (sentences.Length > 1)
            {
                // 跳过第一个可能不完整的句子，从第二个句子开始
                ending = string.Join("", sentences.Skip(1)) + (ending.EndsWith("。") || ending.EndsWith("！") || ending.EndsWith("？") ? "" : "");
            }

            return ending.Trim();
        }

        /// <summary>
        /// 新增：获取章节摘要（开头+结尾的关键部分）
        /// </summary>
        private string GetChapterSummary(string chapterContent, int chapterNumber)
        {
            if (string.IsNullOrEmpty(chapterContent))
                return "";

            try
            {
                // 获取章节开头200字
                var beginningLength = Math.Min(200, chapterContent.Length);
                var beginning = chapterContent.Substring(0, beginningLength);

                // 获取章节结尾200字
                var endingLength = Math.Min(200, chapterContent.Length);
                var startIndex = Math.Max(beginningLength, chapterContent.Length - endingLength);
                var ending = chapterContent.Substring(startIndex);

                // 如果章节很短，直接返回全部内容
                if (chapterContent.Length <= 400)
                {
                    return chapterContent;
                }

                // 组合开头和结尾
                return $"开头：{beginning}...\n结尾：{ending}";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取第{chapterNumber}章摘要失败");
                // 如果出错，返回前300字作为摘要
                var fallbackLength = Math.Min(300, chapterContent.Length);
                return chapterContent.Substring(0, fallbackLength) + "...";
            }
        }

        /// <summary>
        /// 新增：更新时间线内容
        /// </summary>
        private string UpdateTimelineContent(string existingTimeline, int chapterNumber, string chapterSummary)
        {
            var lines = existingTimeline.Split('\n').ToList();

            // 查找是否已存在该章节的时间线
            var chapterLineIndex = lines.FindIndex(line => line.Contains($"第{chapterNumber}章"));

            if (chapterLineIndex >= 0)
            {
                // 更新现有章节时间线
                lines[chapterLineIndex] = $"## 第{chapterNumber}章时间线";

                // 删除旧的章节内容
                var nextChapterIndex = lines.FindIndex(chapterLineIndex + 1, line => line.StartsWith("## 第"));
                if (nextChapterIndex > 0)
                {
                    lines.RemoveRange(chapterLineIndex + 1, nextChapterIndex - chapterLineIndex - 1);
                }
                else
                {
                    // 删除到文件末尾
                    if (chapterLineIndex + 1 < lines.Count)
                    {
                        lines.RemoveRange(chapterLineIndex + 1, lines.Count - chapterLineIndex - 1);
                    }
                }

                // 插入新的章节内容
                lines.Insert(chapterLineIndex + 1, chapterSummary);
                lines.Insert(chapterLineIndex + 2, "");
            }
            else
            {
                // 添加新的章节时间线
                if (string.IsNullOrEmpty(existingTimeline))
                {
                    lines.Add("# 故事时间线");
                    lines.Add("");
                }

                lines.Add($"## 第{chapterNumber}章时间线");
                lines.Add(chapterSummary);
                lines.Add("");
            }

            return string.Join("\n", lines);
        }

        /// <summary>
        /// 新增：基于上下文生成下一章细纲
        /// </summary>
        private async Task<string> GenerateNextChapterOutlineWithContextAsync(
            StepExecutionState state,
            int nextChapterNumber,
            VolumeOutline volume,
            string previousChapterEnding)
        {
            try
            {
                // 获取项目路径
                var projectPath = await GetProjectPathAsync(state.NovelProjectId);

                // 读取相关的世界设定文件
                var worldSettingsDict = await ReadRelevantWorldSettingsForChapterAsync(projectPath, nextChapterNumber, volume);

                // 获取前几章的细纲作为上下文
                var previousOutlinesList = GetPreviousChapterOutlines(state, nextChapterNumber, 2);

                // 检查是否是新卷的第一章
                string previousVolumeTimeline = "";
                bool isNewVolumeFirstChapter = (nextChapterNumber == volume.StartChapter && volume.VolumeNumber > 1);

                if (isNewVolumeFirstChapter)
                {
                    // 获取上一卷的时间线
                    var previousVolumeNumber = volume.VolumeNumber - 1;
                    previousVolumeTimeline = await ReadVolumeTimelineByOutlinesAsync(projectPath, previousVolumeNumber, state.VolumeOutlines);

                    if (!string.IsNullOrEmpty(previousVolumeTimeline))
                    {
                        // 限制时间线长度
                        if (previousVolumeTimeline.Length > 1500)
                        {
                            previousVolumeTimeline = previousVolumeTimeline.Substring(0, 1500) + "...[上一卷时间线已截断]";
                        }
                    }
                }

                // 转换为字符串格式
                var worldSettings = ConvertWorldSettingsToString(worldSettingsDict);
                var previousOutlines = string.Join("\n\n", previousOutlinesList);

                // 构建针对下一章的提示词（增强版，支持跨卷）
                var prompt = BuildNextChapterOutlinePromptEnhanced(
                    state, nextChapterNumber, volume, worldSettings, previousOutlines, previousChapterEnding, previousVolumeTimeline);

                // 生成下一章细纲
                return await _aiService.GenerateTextAsync(prompt, 3000, 0.8f);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"生成第{nextChapterNumber}章细纲失败");
                return "";
            }
        }

        /// <summary>
        /// 新增：构建下一章细纲的提示词
        /// </summary>
        private string BuildNextChapterOutlinePrompt(
            StepExecutionState state,
            int chapterNumber,
            VolumeOutline volume,
            string worldSettings,
            string previousOutlines,
            string previousChapterEnding)
        {
            var prompt = $@"
=== 创作任务 ===
请为第{chapterNumber}章生成详细的章节细纲。

=== 全书信息 ===
书名：{state.BookTitle}
创作方向：{state.CreativeDirection}
目标字数：{state.WordsPerChapter}字

=== 卷宗信息 ===
第{volume.VolumeNumber}卷：{volume.Title}
卷宗描述：{volume.Description}

=== 前文结尾 ===
{previousChapterEnding}

{previousOutlines}

{worldSettings}

=== 细纲要求 ===
请严格按照以下格式生成第{chapterNumber}章的详细细纲：

## 第{chapterNumber}章：[章节标题]

### 场景设定
- 时间：[具体时间]
- 地点：[详细地点描述]
- 环境：[环境氛围和背景]
- 道具：[重要道具和物品]

### 人物安排
- 主要人物：[本章出场的主要角色及其状态]
- 次要人物：[配角和群众角色]
- 人物关系：[角色间的关系变化]
- 人物心理：[关键角色的心理状态]

### 主线发展
- 核心事件：[本章的核心情节]
- 爽点设计：[读者期待的精彩内容]
- 冲突点：[矛盾和冲突的爆发]
- 悬念设置：[留给读者的疑问和期待]

### 预期结果
- 情节推进：[对整体故事的推进作用]
- 角色成长：[角色的变化和成长]
- 伏笔铺设：[为后续章节埋下的伏笔]
- 章节结尾：[本章的结束方式和过渡]

=== 特别要求 ===
1. 必须与前一章的结尾自然衔接
2. 严格遵循全书大纲和卷宗设定
3. 充分利用世界观设定中的元素
4. 避免与前文重复的剧情内容
5. 保持故事的连贯性和逻辑性
6. 确保章节内容丰富，能够支撑{state.WordsPerChapter}字的正文
7. 设计引人入胜的情节发展和角色互动

请生成完整的章节细纲：";

            return prompt;
        }

        /// <summary>
        /// 新增：构建下一章细纲的增强提示词（支持跨卷）
        /// </summary>
        private string BuildNextChapterOutlinePromptEnhanced(
            StepExecutionState state,
            int chapterNumber,
            VolumeOutline volume,
            string worldSettings,
            string previousOutlines,
            string previousChapterEnding,
            string previousVolumeTimeline = "")
        {
            var isNewVolumeFirstChapter = !string.IsNullOrEmpty(previousVolumeTimeline);

            var prompt = $@"
=== 创作任务 ===
请为第{chapterNumber}章生成详细的章节细纲。
{(isNewVolumeFirstChapter ? $"【重要】本章是第{volume.VolumeNumber}卷的开篇章节，需要承接上一卷的剧情发展。" : "")}

=== 全书信息 ===
书名：{state.BookTitle}
创作方向：{state.CreativeDirection}
目标字数：{state.WordsPerChapter}字

=== 卷宗信息 ===
第{volume.VolumeNumber}卷：{volume.Title}
卷宗描述：{volume.Description}

{(isNewVolumeFirstChapter ? $@"
=== 上一卷时间线总结 ===
{previousVolumeTimeline}
" : "")}

=== 前文结尾 ===
{previousChapterEnding}

{previousOutlines}

{worldSettings}

=== 细纲要求 ===
请严格按照以下格式生成第{chapterNumber}章的详细细纲：

## 第{chapterNumber}章：[章节标题]

### 场景设定
- 时间：[具体时间]
- 地点：[详细地点描述]
- 环境：[环境氛围和背景]
- 道具：[重要道具和物品]

### 人物安排
- 主要人物：[本章出场的主要角色及其状态]
- 次要人物：[配角和群众角色]
- 人物关系：[角色间的关系变化]
- 人物心理：[关键角色的心理状态]

### 主线发展
- 核心事件：[本章的核心情节]
- 爽点设计：[读者期待的精彩内容]
- 冲突点：[矛盾和冲突的爆发]
- 悬念设置：[留给读者的疑问和期待]

### 预期结果
- 情节推进：[对整体故事的推进作用]
- 角色成长：[角色的变化和成长]
- 伏笔铺设：[为后续章节埋下的伏笔]
- 章节结尾：[本章的结束方式和过渡]

=== 特别要求 ===
1. {(isNewVolumeFirstChapter ? "作为新卷开篇，必须承接上一卷的剧情发展，同时开启新的故事线" : "必须与前一章的结尾自然衔接")}
2. 严格遵循全书大纲和卷宗设定
3. 充分利用世界观设定中的元素
4. 避免与前文重复的剧情内容
5. 保持故事的连贯性和逻辑性
6. 确保章节内容丰富，能够支撑{state.WordsPerChapter}字的正文
7. 设计引人入胜的情节发展和角色互动
{(isNewVolumeFirstChapter ? "8. 总结前卷成果，预示新卷挑战和机遇" : "")}

请生成完整的章节细纲：";

            return prompt;
        }

        /// <summary>
        /// 将世界设定字典转换为字符串格式
        /// </summary>
        private string ConvertWorldSettingsToString(Dictionary<string, string> worldSettings)
        {
            if (worldSettings == null || !worldSettings.Any())
                return "";

            var settingsText = "\n=== 相关世界设定 ===\n";
            foreach (var setting in worldSettings)
            {
                var content = setting.Value;
                if (content.Length > 300)
                {
                    content = content.Substring(0, 300) + "...";
                }
                settingsText += $"{setting.Key}：{content}\n\n";
            }

            return settingsText;
        }

        /// <summary>
        /// 生成章节正文并验证字数
        /// </summary>
        private async Task<string> GenerateChapterWithWordCountValidationAsync(
            string chapterOutline,
            string context,
            int targetWordCount,
            CancellationToken cancellationToken)
        {
            const int maxRetries = 3;
            const double minWordCountRatio = 0.85; // 最少85%的目标字数
            const double maxWordCountRatio = 1.15; // 最多115%的目标字数

            // 获取AI配置以确定是否使用分段生成
            var aiConfig = await GetAIConfigurationAsync();
            var useSegmentedGeneration = aiConfig?.EnableSegmentedGeneration ?? false;
            var segmentThreshold = aiConfig?.SegmentationThreshold ?? 5000;

            for (int attempt = 1; attempt <= maxRetries; attempt++)
            {
                cancellationToken.ThrowIfCancellationRequested();

                _logger.LogInformation($"开始第{attempt}次章节正文生成，目标字数: {targetWordCount}，分段生成: {useSegmentedGeneration}");

                // 根据配置和目标字数选择生成策略
                string chapterContent;
                if (useSegmentedGeneration && targetWordCount > segmentThreshold)
                {
                    // 使用分段生成策略
                    chapterContent = await GenerateChapterInSegmentsAsync(chapterOutline, context, targetWordCount, cancellationToken);
                }
                else
                {
                    // 使用单次生成策略（一次性生成全部内容）
                    _logger.LogInformation($"使用单次生成策略，目标字数: {targetWordCount}");
                    chapterContent = await _aiService.GenerateChapterAsync(chapterOutline, context, targetWordCount);
                }

                if (string.IsNullOrEmpty(chapterContent))
                {
                    _logger.LogWarning($"第{attempt}次生成的章节内容为空");
                    continue;
                }

                // 计算实际字数
                var actualWordCount = CountChineseCharacters(chapterContent);
                var minWordCount = (int)(targetWordCount * minWordCountRatio);
                var maxWordCount = (int)(targetWordCount * maxWordCountRatio);

                _logger.LogInformation($"第{attempt}次生成完成，实际字数: {actualWordCount}，目标范围: {minWordCount}-{maxWordCount}");

                // 检查字数是否在合理范围内
                if (actualWordCount >= minWordCount && actualWordCount <= maxWordCount)
                {
                    _logger.LogInformation($"字数验证通过，返回内容");
                    return chapterContent;
                }

                // 字数不达标，尝试修正
                if (actualWordCount < minWordCount)
                {
                    _logger.LogWarning($"字数不足({actualWordCount}/{targetWordCount})，尝试扩展内容");

                    if (attempt < maxRetries)
                    {
                        // 尝试扩展内容
                        var expandedContent = await TryExpandChapterContentAsync(chapterContent, chapterOutline, targetWordCount - actualWordCount, cancellationToken);
                        if (!string.IsNullOrEmpty(expandedContent))
                        {
                            var expandedWordCount = CountChineseCharacters(expandedContent);
                            if (expandedWordCount >= minWordCount)
                            {
                                _logger.LogInformation($"内容扩展成功，最终字数: {expandedWordCount}");
                                return expandedContent;
                            }
                        }
                    }
                }
                else if (actualWordCount > maxWordCount)
                {
                    _logger.LogWarning($"字数超标({actualWordCount}/{targetWordCount})，尝试精简内容");

                    if (attempt < maxRetries)
                    {
                        // 尝试精简内容
                        var trimmedContent = await TryTrimChapterContentAsync(chapterContent, targetWordCount, cancellationToken);
                        if (!string.IsNullOrEmpty(trimmedContent))
                        {
                            var trimmedWordCount = CountChineseCharacters(trimmedContent);
                            if (trimmedWordCount <= maxWordCount && trimmedWordCount >= minWordCount)
                            {
                                _logger.LogInformation($"内容精简成功，最终字数: {trimmedWordCount}");
                                return trimmedContent;
                            }
                        }
                    }
                }

                if (attempt == maxRetries)
                {
                    // 如果有内容但字数不足，仍然返回内容而不是抛出异常
                    if (!string.IsNullOrEmpty(chapterContent))
                    {
                        var finalWordCount = CountChineseCharacters(chapterContent);
                        _logger.LogWarning($"经过{maxRetries}次尝试，字数仍不理想（{finalWordCount}/{targetWordCount}），但返回现有内容");
                        return chapterContent;
                    }
                }

                // 等待一段时间再重试
                await Task.Delay(2000, cancellationToken);
            }

            // 获取AI配置信息用于错误诊断
            var aiConfigForDiagnostic = await GetAIConfigurationAsync();
            var configInfo = aiConfigForDiagnostic != null ?
                $"当前配置：平台={aiConfigForDiagnostic.Platform}, MaxTokens={aiConfigForDiagnostic.MaxTokens}, 分段生成={aiConfigForDiagnostic.EnableSegmentedGeneration}, 分段阈值={aiConfigForDiagnostic.SegmentationThreshold}" :
                "无法获取AI配置信息";

            // 提供更详细的错误信息
            var errorMessage = $"章节生成失败：经过{maxRetries}次尝试仍无法生成有效内容。\n\n" +
                             $"配置信息：{configInfo}\n" +
                             $"目标字数：{targetWordCount}字\n\n" +
                             "可能原因：\n" +
                             "1. AI模型负载过高或内存不足\n" +
                             "2. 网络连接不稳定或API服务异常\n" +
                             "3. 提示词过长或复杂，超出模型处理能力\n" +
                             "4. MaxTokens设置过小，无法生成足够长度的内容\n" +
                             "5. 模型配置不当或未正确加载\n\n" +
                             "建议解决方案：\n" +
                             "- 启用分段生成功能（在AI模型配置中设置）\n" +
                             "- 增加MaxTokens设置（建议16384或更高）\n" +
                             "- 重启AI服务并重新加载模型\n" +
                             "- 检查网络连接和API服务状态\n" +
                             "- 尝试使用较小的模型或减少单次生成字数\n" +
                             "- 调整分段字数设置（建议1000-2000字）";

            throw new InvalidOperationException(errorMessage);
        }

        /// <summary>
        /// 计算中文字符数
        /// </summary>
        private int CountChineseCharacters(string text)
        {
            if (string.IsNullOrEmpty(text))
                return 0;

            // 移除空白字符，只计算实际内容字符
            var cleanText = text.Replace(" ", "").Replace("\t", "").Replace("\n", "").Replace("\r", "");

            // 计算中文字符、英文单词和数字
            int count = 0;
            bool inEnglishWord = false;

            foreach (char c in cleanText)
            {
                if (char.IsWhiteSpace(c))
                {
                    inEnglishWord = false;
                    continue;
                }

                if (IsChinese(c))
                {
                    count++;
                    inEnglishWord = false;
                }
                else if (char.IsLetter(c) || char.IsDigit(c))
                {
                    if (!inEnglishWord)
                    {
                        count++; // 英文单词或数字序列算作一个字符
                        inEnglishWord = true;
                    }
                }
                else
                {
                    count++; // 标点符号等
                    inEnglishWord = false;
                }
            }

            return count;
        }

        /// <summary>
        /// 判断是否为中文字符
        /// </summary>
        private bool IsChinese(char c)
        {
            return c >= 0x4e00 && c <= 0x9fff;
        }

        /// <summary>
        /// 尝试扩展章节内容
        /// </summary>
        private async Task<string> TryExpandChapterContentAsync(
            string originalContent,
            string chapterOutline,
            int additionalWords,
            CancellationToken cancellationToken)
        {
            try
            {
                // 分析原内容的字数和结构
                var originalWordCount = CountChineseCharacters(originalContent);
                var targetTotalWords = originalWordCount + additionalWords;

                _logger.LogInformation($"内容扩展：原字数={originalWordCount}，需增加={additionalWords}，目标总字数={targetTotalWords}");

                var prompt = $@"你是一位专业的小说作家，需要对以下章节内容进行扩展。

=== 原始内容（{originalWordCount}字）===
{originalContent}

=== 章节细纲 ===
{chapterOutline}

=== 扩展任务 ===
**目标：将内容从{originalWordCount}字扩展到约{targetTotalWords}字（增加{additionalWords}字）**

=== 扩展策略 ===
1. **环境描写扩展**：增加场景的视觉、听觉、嗅觉等感官描写
2. **人物心理扩展**：深入挖掘人物的内心活动、情感变化、回忆片段
3. **对话丰富化**：扩展现有对话，增加语气、表情、动作描写
4. **细节补充**：增加服装、武器、法术等具体描写
5. **情节铺垫**：适当增加情节转折的铺垫和过渡

=== 扩展要求 ===
- 严格保持原有情节主线和人物设定
- 确保扩展内容与原文风格完全一致
- 重点扩展薄弱环节，让内容更加丰满
- 不要重复原有内容，而是在原基础上深化
- **必须达到约{targetTotalWords}字的目标字数**

请返回完整的扩展后章节内容：";

                // 计算合适的token数量
                var estimatedTokens = (int)(targetTotalWords * 1.5) + 1000;

                return await _aiService.GenerateTextAsync(prompt, estimatedTokens, 0.7f);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"扩展章节内容失败: {ex.Message}");

                // 如果扩展失败，尝试简单的重新生成
                try
                {
                    _logger.LogInformation("尝试使用简化策略重新生成内容");
                    var simplePrompt = $@"请根据以下大纲重新创作章节内容，要求约{additionalWords + CountChineseCharacters(originalContent)}字：

{chapterOutline}

参考原内容风格：
{originalContent.Substring(0, Math.Min(500, originalContent.Length))}...

请创作完整的章节内容：";

                    return await _aiService.GenerateTextAsync(simplePrompt, (additionalWords + CountChineseCharacters(originalContent)) * 2, 0.8f);
                }
                catch (Exception ex2)
                {
                    _logger.LogError(ex2, "简化策略也失败，返回原内容");
                    return originalContent; // 返回原内容而不是空字符串
                }
            }
        }

        /// <summary>
        /// 尝试精简章节内容
        /// </summary>
        private async Task<string> TryTrimChapterContentAsync(
            string originalContent,
            int targetWordCount,
            CancellationToken cancellationToken)
        {
            try
            {
                var prompt = $@"请对以下章节内容进行精简，要求：

=== 原始内容 ===
{originalContent}

=== 精简要求 ===
1. 将内容精简到约{targetWordCount}字
2. 保留所有关键情节和重要对话
3. 保持故事的完整性和连贯性
4. 可以适当删减：
   - 过于冗长的环境描写
   - 重复的心理描写
   - 不必要的细节描述
   - 过多的修饰词语
5. 确保精简后的内容仍然生动有趣
6. 不要删除关键的人物互动和情节转折
7. 返回完整的精简后内容

请返回精简后的完整章节内容：";

                return await _aiService.GenerateTextAsync(prompt, Math.Max(targetWordCount + 1000, 3000), 0.6f);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "精简章节内容失败");
                return "";
            }
        }

        /// <summary>
        /// 获取AI配置
        /// </summary>
        private async Task<AIModelConfig?> GetAIConfigurationAsync()
        {
            try
            {
                // 尝试从服务提供者获取AI配置服务
                var configService = _serviceProvider?.GetService<IAIModelConfigService>();
                if (configService != null)
                {
                    var config = await configService.GetConfigAsync();
                    _logger.LogInformation($"成功获取AI配置 - 平台: {config.Platform}, MaxTokens: {config.MaxTokens}");
                    return config;
                }

                _logger.LogWarning("无法获取AI配置服务，创建默认配置");

                // 创建一个适合章节生成的默认配置
                var defaultConfig = new AIModelConfig
                {
                    Platform = "LMStudio",
                    Temperature = 0.8f,
                    MaxTokens = 16384, // 增加到16K tokens，适合长文本生成
                    EnableThinkingChain = true,
                    EnableSegmentedGeneration = true, // 启用分段生成，避免长文本生成失败
                    SegmentationThreshold = 3000, // 降低阈值
                    SegmentWordCount = 1500, // 每段1500字
                    Timeout = 1800 // 增加超时时间到30分钟
                };

                _logger.LogInformation($"使用默认AI配置 - MaxTokens: {defaultConfig.MaxTokens}");
                return defaultConfig;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取AI配置时发生错误，使用默认配置");

                // 返回一个安全的默认配置
                return new AIModelConfig
                {
                    Platform = "LMStudio",
                    Temperature = 0.8f,
                    MaxTokens = 16384,
                    EnableSegmentedGeneration = false,
                    SegmentationThreshold = 5000,
                    Timeout = 1800 // 30分钟超时
                };
            }
        }

        /// <summary>
        /// 分段生成章节内容
        /// </summary>
        private async Task<string> GenerateChapterInSegmentsAsync(
            string chapterOutline,
            string context,
            int targetWordCount,
            CancellationToken cancellationToken)
        {
            try
            {
                // 获取AI配置中的分段字数设置
                var aiConfig = await GetAIConfigurationAsync();
                var segmentSize = aiConfig?.SegmentWordCount ?? 1500; // 使用配置的分段字数，默认1500
                var segments = Math.Max(1, (targetWordCount + segmentSize - 1) / segmentSize); // 向上取整
                var actualSegmentSize = targetWordCount / segments; // 实际每段字数

                _logger.LogInformation($"使用分段生成策略，总字数: {targetWordCount}，分{segments}段，每段约{actualSegmentSize}字（配置分段字数: {segmentSize}）");

                var fullContent = new StringBuilder();
                var totalWordCount = 0;

                for (int i = 0; i < segments; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var isFirstSegment = i == 0;
                    var isLastSegment = i == segments - 1;
                    var remainingWords = targetWordCount - totalWordCount;
                    var currentSegmentTarget = isLastSegment ? remainingWords : actualSegmentSize;

                    _logger.LogInformation($"生成第{i + 1}/{segments}段，目标字数: {currentSegmentTarget}");

                    string segmentPrompt;
                    if (isFirstSegment)
                    {
                        // 第一段：根据细纲开始创作
                        segmentPrompt = $@"你是一位专业的小说作家，请根据以下章节细纲创作小说章节的开头部分。

=== 章节细纲 ===
{chapterOutline}

=== 上下文信息 ===
{context}

=== 创作要求 ===
1. 这是章节的第1/{segments}部分，约{currentSegmentTarget}字
2. 必须写成标准的小说正文格式，包含场景描写、人物对话、心理描写、动作描写等
3. 严格按照细纲设定场景和人物，但要用生动的小说语言表现
4. 不要写成大纲、摘要或分析形式
5. 不要包含任何标题、章节号或结构性标记
6. 直接开始故事情节，营造引人入胜的开头
7. 为后续内容做好自然的铺垫

请直接创作小说正文：";
                    }
                    else if (isLastSegment)
                    {
                        // 最后一段：完成章节
                        segmentPrompt = $@"你是一位专业的小说作家，请继续并完成以下章节内容。

=== 已有内容 ===
{fullContent}

=== 章节细纲 ===
{chapterOutline}

=== 创作要求 ===
1. 这是章节的第{i + 1}/{segments}部分（最后一段），约{currentSegmentTarget}字
2. 必须写成标准的小说正文格式，与前文风格完全一致
3. 严格按照细纲完成所有关键情节，但要用生动的小说语言表现
4. 不要写成大纲、摘要或分析形式
5. 不要包含任何标题、章节号或结构性标记
6. 自然衔接前文，完成章节的核心冲突和情节发展
7. 给出合适的章节结尾，为下一章做好铺垫
8. 确保整个章节情节完整、逻辑连贯

请直接完成小说正文：";
                    }
                    else
                    {
                        // 中间段：继续发展情节
                        segmentPrompt = $@"你是一位专业的小说作家，请继续以下章节内容。

=== 已有内容 ===
{fullContent}

=== 章节细纲 ===
{chapterOutline}

=== 创作要求 ===
1. 这是章节的第{i + 1}/{segments}部分，约{currentSegmentTarget}字
2. 必须写成标准的小说正文格式，与前文风格完全一致
3. 严格按照细纲继续发展情节，但要用生动的小说语言表现
4. 不要写成大纲、摘要或分析形式
5. 不要包含任何标题、章节号或结构性标记
6. 自然衔接前文，推进故事发展
7. 为后续内容做好过渡，但不要结束章节
8. 保持人物性格和对话风格的一致性

请直接继续小说正文：";
                    }

                    var segmentContent = await _aiService.GenerateTextAsync(segmentPrompt, Math.Max(currentSegmentTarget + 500, 1000), 0.8f);

                    if (!string.IsNullOrEmpty(segmentContent))
                    {
                        fullContent.AppendLine(segmentContent);
                        var segmentWordCount = CountChineseCharacters(segmentContent);
                        totalWordCount += segmentWordCount;

                        _logger.LogInformation($"第{i + 1}段生成完成，字数: {segmentWordCount}，累计: {totalWordCount}");
                    }

                    // 段间延迟，避免API限制
                    if (i < segments - 1)
                    {
                        await Task.Delay(1000, cancellationToken);
                    }
                }

                var finalContent = fullContent.ToString().Trim();
                var finalWordCount = CountChineseCharacters(finalContent);

                _logger.LogInformation($"分段生成完成，最终字数: {finalWordCount}，目标字数: {targetWordCount}");

                return finalContent;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "分段生成章节内容失败");
                throw;
            }
        }

        /// <summary>
        /// 读取分卷时间线内容
        /// </summary>
        private async Task<string> ReadVolumeTimelineAsync(string projectPath, int volumeNumber)
        {
            try
            {
                // 时间线文件路径
                var timelinePath = Path.Combine(projectPath, "设定", "时间线管理.md");

                if (!File.Exists(timelinePath))
                {
                    _logger.LogWarning($"时间线文件不存在: {timelinePath}");
                    return "";
                }

                var timelineContent = await File.ReadAllTextAsync(timelinePath);

                // 提取指定卷的时间线内容
                return ExtractVolumeTimelineFromContent(timelineContent, volumeNumber);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"读取第{volumeNumber}卷时间线失败");
                return "";
            }
        }

        /// <summary>
        /// 从时间线内容中提取指定卷的时间线
        /// </summary>
        private string ExtractVolumeTimelineFromContent(string timelineContent, int volumeNumber)
        {
            try
            {
                if (string.IsNullOrEmpty(timelineContent))
                    return "";

                var lines = timelineContent.Split('\n');
                var volumeTimeline = new List<string>();
                bool inTargetVolume = false;
                bool foundTargetVolume = false;

                foreach (var line in lines)
                {
                    // 检查是否是章节标题行
                    if (line.StartsWith("## 第") && line.Contains("章时间线"))
                    {
                        // 提取章节号
                        var chapterMatch = System.Text.RegularExpressions.Regex.Match(line, @"第(\d+)章");
                        if (chapterMatch.Success && int.TryParse(chapterMatch.Groups[1].Value, out int chapterNumber))
                        {
                            // 判断该章节是否属于目标卷
                            // 这里需要根据章节号判断所属卷，假设每卷100章
                            int chapterVolume = (chapterNumber - 1) / 100 + 1; // 简化计算，实际应该根据VolumeOutlines计算

                            if (chapterVolume == volumeNumber)
                            {
                                inTargetVolume = true;
                                foundTargetVolume = true;
                                volumeTimeline.Add(line);
                            }
                            else if (inTargetVolume)
                            {
                                // 已经超出目标卷的范围
                                break;
                            }
                        }
                    }
                    else if (inTargetVolume)
                    {
                        volumeTimeline.Add(line);
                    }
                }

                return foundTargetVolume ? string.Join("\n", volumeTimeline) : "";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"提取第{volumeNumber}卷时间线失败");
                return "";
            }
        }

        /// <summary>
        /// 根据章节号和卷宗信息判断章节所属卷
        /// </summary>
        private int GetVolumeNumberByChapter(int chapterNumber, List<VolumeOutline> volumeOutlines)
        {
            foreach (var volume in volumeOutlines)
            {
                if (chapterNumber >= volume.StartChapter && chapterNumber <= volume.EndChapter)
                {
                    return volume.VolumeNumber;
                }
            }
            return 1; // 默认返回第1卷
        }

        /// <summary>
        /// 读取指定卷的完整时间线（改进版，使用VolumeOutlines准确判断）
        /// </summary>
        private async Task<string> ReadVolumeTimelineByOutlinesAsync(string projectPath, int volumeNumber, List<VolumeOutline> volumeOutlines)
        {
            try
            {
                var timelinePath = Path.Combine(projectPath, "设定", "时间线管理.md");

                if (!File.Exists(timelinePath))
                {
                    return "";
                }

                var timelineContent = await File.ReadAllTextAsync(timelinePath);

                // 找到目标卷的章节范围
                var targetVolume = volumeOutlines.FirstOrDefault(v => v.VolumeNumber == volumeNumber);
                if (targetVolume == null)
                {
                    return "";
                }

                return ExtractVolumeTimelineByChapterRange(timelineContent, targetVolume.StartChapter, targetVolume.EndChapter);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"读取第{volumeNumber}卷时间线失败");
                return "";
            }
        }

        /// <summary>
        /// 根据章节范围提取时间线内容
        /// </summary>
        private string ExtractVolumeTimelineByChapterRange(string timelineContent, int startChapter, int endChapter)
        {
            try
            {
                if (string.IsNullOrEmpty(timelineContent))
                    return "";

                var lines = timelineContent.Split('\n');
                var volumeTimeline = new List<string>();
                bool inTargetRange = false;

                foreach (var line in lines)
                {
                    // 检查是否是章节标题行
                    if (line.StartsWith("## 第") && line.Contains("章时间线"))
                    {
                        var chapterMatch = System.Text.RegularExpressions.Regex.Match(line, @"第(\d+)章");
                        if (chapterMatch.Success && int.TryParse(chapterMatch.Groups[1].Value, out int chapterNumber))
                        {
                            if (chapterNumber >= startChapter && chapterNumber <= endChapter)
                            {
                                inTargetRange = true;
                                volumeTimeline.Add(line);
                            }
                            else if (chapterNumber > endChapter)
                            {
                                // 超出范围，停止提取
                                break;
                            }
                            else
                            {
                                inTargetRange = false;
                            }
                        }
                    }
                    else if (inTargetRange)
                    {
                        volumeTimeline.Add(line);
                    }
                }

                return string.Join("\n", volumeTimeline);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "根据章节范围提取时间线失败");
                return "";
            }
        }

        /// <summary>
        /// 清理重复的章节文件
        /// </summary>
        private async Task CleanupDuplicateChapterFilesAsync(string contentDir, string bookTitle, int chapterNumber, string currentFilePath)
        {
            try
            {
                if (!Directory.Exists(contentDir))
                    return;

                var sanitizedBookTitle = _fileNamingService.SanitizeFileName(bookTitle);

                // 更精确的查找同一章节的所有文件
                var allFiles = Directory.GetFiles(contentDir, "*.txt", SearchOption.TopDirectoryOnly);
                var filesToDelete = new List<string>();

                foreach (var file in allFiles)
                {
                    var fileName = Path.GetFileNameWithoutExtension(file);

                    // 检查是否是同一本书的同一章节
                    if (fileName.StartsWith(sanitizedBookTitle, StringComparison.OrdinalIgnoreCase))
                    {
                        // 使用正则表达式匹配章节号
                        var chapterPatterns = new[]
                        {
                            $@"第{chapterNumber:D3}章",
                            $@"第{chapterNumber:D2}章",
                            $@"第{chapterNumber}章",
                            $@"_{chapterNumber:D3}_",
                            $@"_{chapterNumber:D2}_",
                            $@"_{chapterNumber}_"
                        };

                        bool isMatchingChapter = false;
                        foreach (var pattern in chapterPatterns)
                        {
                            if (System.Text.RegularExpressions.Regex.IsMatch(fileName, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                            {
                                isMatchingChapter = true;
                                break;
                            }
                        }

                        // 如果是同一章节的文件，且不是当前要保存的文件，则标记为删除
                        if (isMatchingChapter && !string.Equals(file, currentFilePath, StringComparison.OrdinalIgnoreCase))
                        {
                            filesToDelete.Add(file);
                        }
                    }
                }

                // 删除重复文件
                foreach (var fileToDelete in filesToDelete.Distinct())
                {
                    try
                    {
                        File.Delete(fileToDelete);
                        _logger.LogInformation($"已删除重复的章节文件: {Path.GetFileName(fileToDelete)}");
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, $"删除重复文件失败: {fileToDelete}");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"清理第{chapterNumber}章重复文件时发生错误");
            }
        }

        /// <summary>
        /// 章节完成后的后处理流程
        /// </summary>
        private async Task PostProcessChapterAsync(StepExecutionState state, int chapterNumber, string chapterContent)
        {
            try
            {
                _logger.LogInformation($"开始执行第{chapterNumber}章后处理流程");

                // 1. 更新时间线
                if (_timelineService != null)
                {
                    await _timelineService.UpdateChapterTimelineAsync(
                        state.NovelProjectId, chapterNumber, chapterContent,
                        state.ChapterTitles.GetValueOrDefault(chapterNumber, $"第{chapterNumber}章"));
                }

                // 2. 更新角色信息
                if (_characterUpdateService != null)
                {
                    await _characterUpdateService.UpdateCharactersAfterChapterAsync(
                        state.NovelProjectId, chapterNumber, chapterContent,
                        state.ChapterTitles.GetValueOrDefault(chapterNumber, $"第{chapterNumber}章"));
                }

                // 3. 更新后续章节细纲
                if (_chapterOutlineUpdateService != null)
                {
                    await _chapterOutlineUpdateService.UpdateSubsequentChapterOutlinesAsync(
                        state.NovelProjectId, chapterNumber, chapterContent, 3);
                }

                state.LastUpdated = DateTime.Now;
                _logger.LogInformation($"第{chapterNumber}章后处理流程完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"第{chapterNumber}章后处理流程失败");
                // 不抛出异常，避免影响主流程
            }
        }

        /// <summary>
        /// 获取章节对应的卷宗
        /// </summary>
        private VolumeOutline? GetCurrentVolumeForChapter(StepExecutionState state, int chapterNumber)
        {
            return state.VolumeOutlines.FirstOrDefault(v =>
                chapterNumber >= v.StartChapter && chapterNumber <= v.EndChapter);
        }
    }
}
